From 81a991735543b016f6ddce7f0514ae2810efd8d4 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 23 Jun 2025 08:10:48 +0200 Subject: [PATCH 01/54] Update for regex 20 lookbehind test. Removed cpp file and added cpp2 file. --- .../pure2-regex_20_lookbehind.cpp | 8989 ----------------- .../pure2-regex_20_lookbehind.cpp2 | 286 + 2 files changed, 286 insertions(+), 8989 deletions(-) delete mode 100644 regression-tests/pure2-regex_20_lookbehind.cpp create mode 100644 regression-tests/pure2-regex_20_lookbehind.cpp2 diff --git a/regression-tests/pure2-regex_20_lookbehind.cpp b/regression-tests/pure2-regex_20_lookbehind.cpp deleted file mode 100644 index 1f549a346..000000000 --- a/regression-tests/pure2-regex_20_lookbehind.cpp +++ /dev/null @@ -1,8989 +0,0 @@ - -#include "cpp2regex.h" - -//=== Cpp2 type declarations ==================================================== - - -#include "cpp2util.h" - -#line 1 "build/20_lookbehind.cpp2" - -#line 166 "build/20_lookbehind.cpp2" -class test_tests_20_lookbehind; - - -//=== Cpp2 type definitions and function declarations =========================== - -#line 1 "build/20_lookbehind.cpp2" -[[nodiscard]] auto create_result(cpp2::impl::in resultExpr, auto const& r) -> std::string; - -#line 113 "build/20_lookbehind.cpp2" -[[nodiscard]] auto sanitize(std::string str) -> std::string; - -#line 125 "build/20_lookbehind.cpp2" -template auto test(M const& regex, cpp2::impl::in id, cpp2::impl::in regex_str, cpp2::impl::in str, cpp2::impl::in kind, cpp2::impl::in resultExpr, - cpp2::impl::in resultExpected) -> void; - -#line 166 "build/20_lookbehind.cpp2" -class test_tests_20_lookbehind { - -#line 223 "build/20_lookbehind.cpp2" - public: auto run() const& -> void; - public: template class regex_01_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_01_matcher() = default; - public: regex_01_matcher(regex_01_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_01_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_01 {}; public: template class regex_02_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_02_matcher() = default; - public: regex_02_matcher(regex_02_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_02_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_02 {}; public: template class regex_03_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_03_matcher() = default; - public: regex_03_matcher(regex_03_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_03_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_03 {}; public: template class regex_04_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_04_matcher() = default; - public: regex_04_matcher(regex_04_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_04_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_04 {}; public: template class regex_05_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_05_matcher() = default; - public: regex_05_matcher(regex_05_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_05_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_05 {}; public: template class regex_06_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_06_matcher() = default; - public: regex_06_matcher(regex_06_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_06_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_06 {}; public: template class regex_07_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_07_matcher() = default; - public: regex_07_matcher(regex_07_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_07_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_07 {}; public: template class regex_08_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_08_matcher() = default; - public: regex_08_matcher(regex_08_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_08_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_08 {}; public: template class regex_09_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_09_matcher() = default; - public: regex_09_matcher(regex_09_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_09_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_09 {}; public: template class regex_10_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_10_matcher() = default; - public: regex_10_matcher(regex_10_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_10_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_10 {}; public: template class regex_11_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_11_matcher() = default; - public: regex_11_matcher(regex_11_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_11_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_11 {}; public: template class regex_12_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_12_matcher() = default; - public: regex_12_matcher(regex_12_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_12_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_12 {}; public: template class regex_13_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_13_matcher() = default; - public: regex_13_matcher(regex_13_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_13_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_13 {}; public: template class regex_14_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_14_matcher() = default; - public: regex_14_matcher(regex_14_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_14_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_14 {}; public: template class regex_15_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_15_matcher() = default; - public: regex_15_matcher(regex_15_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_15_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_15 {}; public: template class regex_16_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_16_matcher() = default; - public: regex_16_matcher(regex_16_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_16_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_16 {}; public: template class regex_17_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_17_matcher() = default; - public: regex_17_matcher(regex_17_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_17_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_17 {}; public: template class regex_18_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_18_matcher() = default; - public: regex_18_matcher(regex_18_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_18_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_18 {}; public: template class regex_19_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_19_matcher() = default; - public: regex_19_matcher(regex_19_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_19_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_19 {}; public: template class regex_20_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_20_matcher() = default; - public: regex_20_matcher(regex_20_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_20_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_20 {}; public: template class regex_21_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_21_matcher() = default; - public: regex_21_matcher(regex_21_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_21_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_21 {}; public: template class regex_22_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_22_matcher() = default; - public: regex_22_matcher(regex_22_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_22_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_22 {}; public: template class regex_23_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_23_matcher() = default; - public: regex_23_matcher(regex_23_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_23_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_23 {}; public: template class regex_24_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_24_matcher() = default; - public: regex_24_matcher(regex_24_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_24_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_24 {}; public: template class regex_25_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_25_matcher() = default; - public: regex_25_matcher(regex_25_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_25_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_25 {}; public: template class regex_26_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_26_matcher() = default; - public: regex_26_matcher(regex_26_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_26_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_26 {}; public: template class regex_27_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_27_matcher() = default; - public: regex_27_matcher(regex_27_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_27_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_27 {}; public: template class regex_28_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_28_matcher() = default; - public: regex_28_matcher(regex_28_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_28_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_28 {}; public: template class regex_29_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_29_matcher() = default; - public: regex_29_matcher(regex_29_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_29_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_29 {}; public: template class regex_30_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_30_matcher() = default; - public: regex_30_matcher(regex_30_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_30_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_30 {}; public: template class regex_31_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_31_matcher() = default; - public: regex_31_matcher(regex_31_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_31_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_31 {}; public: template class regex_32_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_32_matcher() = default; - public: regex_32_matcher(regex_32_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_32_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_32 {}; public: template class regex_33_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_33_matcher() = default; - public: regex_33_matcher(regex_33_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_33_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_33 {}; public: template class regex_34_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_34_matcher() = default; - public: regex_34_matcher(regex_34_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_34_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_34 {}; public: template class regex_35_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_35_matcher() = default; - public: regex_35_matcher(regex_35_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_35_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_35 {}; public: template class regex_36_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_36_matcher() = default; - public: regex_36_matcher(regex_36_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_36_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_36 {}; public: template class regex_37_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_37_matcher() = default; - public: regex_37_matcher(regex_37_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_37_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_37 {}; public: template class regex_38_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_38_matcher() = default; - public: regex_38_matcher(regex_38_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_38_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_38 {}; public: template class regex_39_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_5 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_6 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_39_matcher() = default; - public: regex_39_matcher(regex_39_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_39_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_39 {}; public: template class regex_40_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_40_matcher() = default; - public: regex_40_matcher(regex_40_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_40_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_40 {}; public: template class regex_41_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_41_matcher() = default; - public: regex_41_matcher(regex_41_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_41_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_41 {}; public: template class regex_42_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_42_matcher() = default; - public: regex_42_matcher(regex_42_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_42_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_42 {}; public: template class regex_43_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_43_matcher() = default; - public: regex_43_matcher(regex_43_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_43_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_43 {}; public: template class regex_44_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_44_matcher() = default; - public: regex_44_matcher(regex_44_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_44_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_44 {}; public: template class regex_45_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_45_matcher() = default; - public: regex_45_matcher(regex_45_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_45_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_45 {}; public: template class regex_46_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_46_matcher() = default; - public: regex_46_matcher(regex_46_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_46_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_46 {}; public: template class regex_47_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_47_matcher() = default; - public: regex_47_matcher(regex_47_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_47_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_47 {}; public: template class regex_48_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_48_matcher() = default; - public: regex_48_matcher(regex_48_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_48_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_48 {}; public: template class regex_49_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_49_matcher() = default; - public: regex_49_matcher(regex_49_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_49_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_49 {}; public: template class regex_50_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_50_matcher() = default; - public: regex_50_matcher(regex_50_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_50_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_50 {}; public: template class regex_51_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_51_matcher() = default; - public: regex_51_matcher(regex_51_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_51_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_51 {}; public: template class regex_52_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_52_matcher() = default; - public: regex_52_matcher(regex_52_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_52_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_52 {}; public: template class regex_53_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_53_matcher() = default; - public: regex_53_matcher(regex_53_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_53_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_53 {}; public: template class regex_54_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_54_matcher() = default; - public: regex_54_matcher(regex_54_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_54_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_54 {}; public: template class regex_55_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_3 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_4 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_55_matcher() = default; - public: regex_55_matcher(regex_55_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_55_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_55 {}; public: template class regex_56_matcher { - public: template using context = cpp2::regex::match_context; -public: class func_2 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_1 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: class func_0 { - public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; - - }; - - public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; - - public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; - - public: [[nodiscard]] constexpr static auto is_start_match() -> bool; -public: [[nodiscard]] static auto to_string() -> std::string; - - public: regex_56_matcher() = default; - public: regex_56_matcher(regex_56_matcher const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(regex_56_matcher const&) -> void = delete; - - }; - - public: cpp2::regex::regular_expression> regex_56 {}; - public: test_tests_20_lookbehind() = default; - public: test_tests_20_lookbehind(test_tests_20_lookbehind const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(test_tests_20_lookbehind const&) -> void = delete; - - -#line 283 "build/20_lookbehind.cpp2" -}; -auto main() -> int; - -//=== Cpp2 function definitions ================================================= - -#line 1 "build/20_lookbehind.cpp2" -[[nodiscard]] auto create_result(cpp2::impl::in resultExpr, auto const& r) -> std::string{ -#line 2 "build/20_lookbehind.cpp2" - std::string result {""}; - - auto get_next {[_0 = (&resultExpr)](auto const& iter) mutable -> auto{ - auto start {std::distance(CPP2_UFCS(cbegin)((*cpp2::impl::assert_not_null(_0))), iter)}; - auto firstDollar {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(_0)), "$", start)}; - auto firstAt {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(_0)), "@", cpp2::move(start))}; - - auto end {std::min(cpp2::move(firstDollar), cpp2::move(firstAt))}; - if (end != std::string::npos) { - return CPP2_UFCS(cbegin)((*cpp2::impl::assert_not_null(_0))) + cpp2::move(end); - } - else { - return CPP2_UFCS(cend)((*cpp2::impl::assert_not_null(_0))); - } - }}; - auto extract_group_and_advance {[](auto& iter) -> auto{ - auto start {iter}; - - for( ; std::isdigit(*cpp2::impl::assert_not_null(iter)); ++iter ) {} - - return std::stoi(std::string(cpp2::move(start), iter)); - }}; - auto extract_until {[](auto& iter, cpp2::impl::in to) -> auto{ - auto start {iter}; - - for( ; (to != *cpp2::impl::assert_not_null(iter)); ++iter ) {}// TODO: Without bracket: error: postfix unary * (dereference) cannot be immediately followed by a (, identifier, or literal - add whitespace before * here if you meant binary * (multiplication) - - return std::string(cpp2::move(start), iter); - }}; - - auto iter {CPP2_UFCS(begin)(resultExpr)}; - - while( iter != CPP2_UFCS(end)(resultExpr) ) { - auto next {get_next(iter)}; - - if (next != iter) { - result += std::string(iter, next); - } - if (next != CPP2_UFCS(end)(resultExpr)) { - if (*cpp2::impl::assert_not_null(next) == '$') { - ++next; - - if (*cpp2::impl::assert_not_null(next) == '&') { - ++next; - result += CPP2_UFCS(group)(r, 0); - } - else {if (*cpp2::impl::assert_not_null(next) == '-' || *cpp2::impl::assert_not_null(next) == '+') { - auto is_start {*cpp2::impl::assert_not_null(next) == '-'}; - ++next; - if (*cpp2::impl::assert_not_null(next) == '{') { - ++next; // Skip { - auto group {extract_until(next, '}')}; - ++next; // Skip } - result += CPP2_UFCS(group)(r, cpp2::move(group)); - } - else {if (*cpp2::impl::assert_not_null(next) == '[') { - ++next; // Skip [ - auto group {extract_group_and_advance(next)}; - ++next; // Skip ] - - if (cpp2::move(is_start)) { - result += std::to_string(CPP2_UFCS(group_start)(r, cpp2::move(group))); - } - else { - result += std::to_string(CPP2_UFCS(group_end)(r, cpp2::move(group))); - } - } - else { - // Return max group - result += CPP2_UFCS(group)(r, CPP2_UFCS(group_number)(r) - 1); - }} - } - else {if (std::isdigit(*cpp2::impl::assert_not_null(next))) { - auto group {extract_group_and_advance(next)}; - result += CPP2_UFCS(group)(r, cpp2::move(group)); - } - else { - std::cerr << "Not implemented"; - }}} - } - else {if (*cpp2::impl::assert_not_null(next) == '@') { - ++next; - - if (*cpp2::impl::assert_not_null(next) == '-' || *cpp2::impl::assert_not_null(next) == '+') { - auto i {0}; - for( ; cpp2::impl::cmp_less(i,cpp2::unchecked_narrow(CPP2_UFCS(group_number)(r))); ++i ) { - auto pos {0}; - if (*cpp2::impl::assert_not_null(next) == '-') { - pos = CPP2_UFCS(group_start)(r, i); - } - else { - pos = CPP2_UFCS(group_end)(r, i); - } - result += std::to_string(cpp2::move(pos)); - } - ++next; - } - else { - std::cerr << "Not implemented"; - } - } - else { - std::cerr << "Not implemented."; - }} - } - iter = cpp2::move(next); - } - - return result; -} - -#line 113 "build/20_lookbehind.cpp2" -[[nodiscard]] auto sanitize(std::string str) -> std::string -{ - str = cpp2::string_util::replace_all(str, "\a", "\\a"); - str = cpp2::string_util::replace_all(str, "\f", "\\f"); - str = cpp2::string_util::replace_all(str, "\x1b", "\\e"); - str = cpp2::string_util::replace_all(str, "\n", "\\n"); - str = cpp2::string_util::replace_all(str, "\r", "\\r"); - str = cpp2::string_util::replace_all(str, "\t", "\\t"); - - return cpp2::move(str); -} - -#line 125 "build/20_lookbehind.cpp2" -template auto test(M const& regex, cpp2::impl::in id, cpp2::impl::in regex_str, cpp2::impl::in str, cpp2::impl::in kind, cpp2::impl::in resultExpr, - cpp2::impl::in resultExpected) -> void{ - - std::string warning {""}; - if (CPP2_UFCS(to_string)(regex) != regex_str) { - warning = "Warning: Parsed regex does not match."; - } - - std::string status {"OK"}; - - auto r {CPP2_UFCS(search)(regex, str)}; - - if ("y" == kind || "yM" == kind || "yS" == kind || "yB" == kind) { - if (!(r.matched)) { - status = "Failure: Regex should apply."; - } - else { - // Have a match check the result - - auto result {create_result(resultExpr, cpp2::move(r))}; - - if (result != resultExpected) { - status = "Failure: Result is wrong. (is: " + cpp2::to_string(sanitize(cpp2::move(result))) + ")"; - } - } - } - else {if ("n" == kind) { - if (r.matched) { - status = "Failure: Regex should not apply. Result is '" + cpp2::to_string(CPP2_UFCS(group)(cpp2::move(r), 0)) + "'"; - } - }else { - status = "Unknown kind '" + cpp2::to_string(kind) + "'"; - }} - - if (!(CPP2_UFCS(empty)(warning))) { - warning += " "; - } - std::cout << "" + cpp2::to_string(id) + "_" + cpp2::to_string(kind) + ": " + cpp2::to_string(cpp2::move(status)) + " " + cpp2::to_string(cpp2::move(warning)) + "regex: " + cpp2::to_string(regex_str) + " parsed_regex: " + cpp2::to_string(CPP2_UFCS(to_string)(regex)) + " str: " + cpp2::to_string(sanitize(str)) + " result_expr: " + cpp2::to_string(resultExpr) + " expected_results " + cpp2::to_string(sanitize(resultExpected)) + "" << std::endl; -} - -#line 223 "build/20_lookbehind.cpp2" - auto test_tests_20_lookbehind::run() const& -> void{ - std::cout << "Running tests_20_lookbehind:" << std::endl; - test(regex_01, "01", R"((?<=a)b)", "ab", "y", R"($&)", "b"); - test(regex_02, "02", R"((?<=af?)b)", "ab", "y", R"($&)", "b"); - test(regex_03, "03", R"((?<=a)b)", "cb", "n", R"(-)", "-"); - test(regex_04, "04", R"((?<=a(?:fo)?)b)", "cb", "n", R"(-)", "-"); - test(regex_05, "05", R"((?<=a)b)", "b", "n", R"(-)", "-"); - test(regex_06, "06", R"((?<=a(?:foo)?)b)", "b", "n", R"(-)", "-"); - test(regex_07, "07", R"((?)foo)", "bar>foo", "y", R"($&)", "foo"); - test(regex_50, "50", R"((?)foo)", "bar>foo", "n", R"(-)", "-"); - test(regex_51, "51", R"((?<=bar>ABC)foo)", "bar>ABCfoo", "y", R"($&)", "foo"); - test(regex_52, "52", R"((?ABC)foo)", "bar>ABCfoo", "n", R"(-)", "-"); - test(regex_53, "53", R"((?<=abcd(?<=(aaaabcd))))", "..aaaabcd..", "y", R"($1)", "aaaabcd"); - test(regex_54, "54", R"((?=xy(?<=(aaxy))))", "..aaxy..", "y", R"($1)", "aaxy"); - test(regex_55, "55", R"((?=xy(?<=(aaxyz?))))", "..aaxy..", "y", R"($1)", "aaxy"); - test(regex_56, "56", R"((?<=(?=(aaxy))aa))", "..aaxy..", "y", R"($1)", "aaxy"); - std::cout << std::endl; - } - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_01_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::to_string() -> std::string{return R"((?<=a)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"f"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_02_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::to_string() -> std::string{return R"((?<=af?)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_03_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::to_string() -> std::string{return R"((?<=a)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"of"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 2;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_04_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::to_string() -> std::string{return R"((?<=a(?:fo)?)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_05_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::to_string() -> std::string{return R"((?<=a)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_06_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::to_string() -> std::string{return R"((?<=a(?:foo)?)b)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_07_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"boof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_08_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_09_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"aboof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),5)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,5); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 5;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_10_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_11_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"raboof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),6)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,6); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 6;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_12_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_13_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"braboof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 7;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_14_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_0 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_15_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"e"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_16_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_17_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_18_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_19_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"d"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_4(), func_2(), cpp2::regex::no_reset(), func_3(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - - auto tmp_2_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; - static_cast(cpp2::move(tmp_2)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_3 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_20_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"d"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_4(), func_2(), cpp2::regex::no_reset(), func_3(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - - auto tmp_2_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; - static_cast(cpp2::move(tmp_2)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_21_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"dc"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 2;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_22_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - std::array str_tmp_0 {"a"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - ctx.set_group_start(1, r.pos); - - auto tmp_1_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_1 {cpp2::regex::make_on_return(cpp2::move(tmp_1_func))}; - static_cast(cpp2::move(tmp_1)); - if (!(cpp2::regex::line_start_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::line_end_token_matcher(r.pos, ctx))) {r.matched = false;break;} - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_23_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::to_string() -> std::string{return R"($(?<=^(a)))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_24_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::to_string() -> std::string{return R"((.*)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_25_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::to_string() -> std::string{return R"((.*)(?<=b))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_26_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::to_string() -> std::string{return R"((.*)(?<=b)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_27_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::to_string() -> std::string{return R"((.*)(?<=b|c))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_3 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_28_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::to_string() -> std::string{return R"((.*)(?<=b|c)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_29_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::to_string() -> std::string{return R"((.*)(?<=c|b))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_3 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_30_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::to_string() -> std::string{return R"((.*)(?<=c|b)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_31_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::to_string() -> std::string{return R"((.*)(?<=[bc]))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_32_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::to_string() -> std::string{return R"((.*)(?<=[bc])c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_33_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::to_string() -> std::string{return R"((.*?)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_34_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::to_string() -> std::string{return R"((.*?)(?<=b))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_35_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::to_string() -> std::string{return R"((.*?)(?<=b)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_36_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::to_string() -> std::string{return R"((.*?)(?<=b|c))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_3 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_37_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::to_string() -> std::string{return R"((.*?)(?<=b|c)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_38_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::to_string() -> std::string{return R"((.*?)(?<=c|b))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"b"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_3 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_39_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::to_string() -> std::string{return R"((.*?)(?<=c|b)c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_40_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::to_string() -> std::string{return R"((.*?)(?<=[bc]))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - auto tmp_0_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; - static_cast(cpp2::move(tmp_0)); - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - - std::array str_tmp_1 {"c"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_41_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::to_string() -> std::string{return R"((.*?)(?<=[bc])c)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_42_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::to_string() -> std::string{return R"((?<=foo))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_43_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::to_string() -> std::string{return R"((?<=foo))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_44_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::to_string() -> std::string{return R"(.*(?<=foo))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_45_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::to_string() -> std::string{return R"(.*(?<=foo))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"Y"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_46_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::to_string() -> std::string{return R"((?<=foo)Y)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"o"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_2 {"Y"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_47_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::to_string() -> std::string{return R"(o(?<=foo)Y)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} - - std::array str_tmp_1 {"oof"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"X"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_48_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::to_string() -> std::string{return R"(X(?<=foo.)[YZ])"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {">rab"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"foo"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_49_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::to_string() -> std::string{return R"((?<=bar>)foo)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {">rab"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"foo"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_50_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::to_string() -> std::string{return R"((?)foo)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"CBA>rab"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 7;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"foo"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_51_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::to_string() -> std::string{return R"((?<=bar>ABC)foo)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"CBA>rab"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 7;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - - std::array str_tmp_1 {"foo"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 3;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_52_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::to_string() -> std::string{return R"((?ABC)foo)"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - std::array str_tmp_0 {"dcbaaaa"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 7;} - else {break;} - ctx.set_group_start(1, r.pos); - - auto tmp_1_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_1 {cpp2::regex::make_on_return(cpp2::move(tmp_1_func))}; - static_cast(cpp2::move(tmp_1)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} - - std::array str_tmp_2 {"dcba"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_53_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::to_string() -> std::string{return R"((?<=abcd(?<=(aaaabcd))))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - - std::array str_tmp_1 {"yxaa"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - ctx.set_group_start(1, r.pos); - - auto tmp_2_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; - static_cast(cpp2::move(tmp_2)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"xy"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 2;} - else {break;} - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_54_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::to_string() -> std::string{return R"((?=xy(?<=(aaxy))))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_1 {"z"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 1;} - else {break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_end(1, r.pos); - } - while ( - false - ); - if (r.matched) { - r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_3(), cpp2::regex::no_reset(), other, func_4()); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_2 {"yxaa"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - ctx.set_group_start(1, r.pos); - - auto tmp_3_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_3 {cpp2::regex::make_on_return(cpp2::move(tmp_3_func))}; - static_cast(cpp2::move(tmp_3)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"xy"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 2;} - else {break;} - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_55_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::to_string() -> std::string{return R"((?=xy(?<=(aaxyz?))))"; } - - - - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - ctx.set_group_start(1, r.pos); - - std::array str_tmp_1 {"aaxy"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 4;} - else {break;} - ctx.set_group_end(1, r.pos); - - auto tmp_2_func { -[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ - if (!((*cpp2::impl::assert_not_null(_1)).matched)) { - (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); - } - } - }; - - auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; - static_cast(cpp2::move(tmp_2)); - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - - std::array str_tmp_0 {"aa"}; - if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { - r.matched = false; - break; - } -{ -int i{0}; - for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} - } -} - if (r.matched) {r.pos += 2;} - else {break;} - if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ - - auto r {ctx.pass(cur)}; - do { - if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} - } - while ( - false - ); - if (r.matched) { - r = other(r.pos, ctx); - } - else { - r.pos = ctx.end; - } - static_cast(CPP2_FORWARD(ctx)); - return r; - } - - template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ - ctx.set_group_start(0, cur); - - auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; - if (r.matched) {ctx.set_group_end(0, r.pos);} - return r; - } - - template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::get_named_group_index(auto const& name) -> int{ - static_cast(name); - return -1; - } - - template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_56_matcher::is_start_match() -> bool { return false; } -template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::to_string() -> std::string{return R"((?<=(?=(aaxy))aa))"; } - - -#line 284 "build/20_lookbehind.cpp2" -auto main() -> int{ - CPP2_UFCS(run)(test_tests_20_lookbehind()); -} - diff --git a/regression-tests/pure2-regex_20_lookbehind.cpp2 b/regression-tests/pure2-regex_20_lookbehind.cpp2 new file mode 100644 index 000000000..75ad0ade5 --- /dev/null +++ b/regression-tests/pure2-regex_20_lookbehind.cpp2 @@ -0,0 +1,286 @@ +create_result: (resultExpr: std::string, r) -> std::string = { + result: std::string = ""; + + get_next := :(iter) -> _ = { + start := std::distance(resultExpr&$*.cbegin(), iter); + firstDollar := resultExpr&$*.find("$", start); + firstAt := resultExpr&$*.find("@", start); + + end := std::min(firstDollar, firstAt); + if end != std::string::npos { + return resultExpr&$*.cbegin() + end; + } + else { + return resultExpr&$*.cend(); + } + }; + extract_group_and_advance := :(inout iter) -> _ = { + start := iter; + + while std::isdigit(iter*) next iter++ {} + + return std::stoi(std::string(start, iter)); + }; + extract_until := :(inout iter, to: char) -> _ = { + start := iter; + + while (to != iter*) next iter++ {} // TODO: Without bracket: error: postfix unary * (dereference) cannot be immediately followed by a (, identifier, or literal - add whitespace before * here if you meant binary * (multiplication) + + return std::string(start, iter); + }; + + iter := resultExpr.begin(); + + while iter != resultExpr.end() { + next := get_next(iter); + + if next != iter { + result += std::string(iter, next); + } + if next != resultExpr.end() { + if next* == '$' { + next++; + + if next* == '&' { + next++; + result += r.group(0); + } + else if next* == '-' || next* == '+' { + is_start := next* == '-'; + next++; + if next* == '{' { + next++; // Skip { + group := extract_until(next, '}'); + next++; // Skip } + result += r.group(group); + } + else if next* == '[' { + next++; // Skip [ + group := extract_group_and_advance(next); + next++; // Skip ] + + if is_start { + result += std::to_string(r.group_start(group)); + } + else { + result += std::to_string(r.group_end(group)); + } + } + else { + // Return max group + result += r.group(r.group_number() - 1); + } + } + else if std::isdigit(next*) { + group := extract_group_and_advance(next); + result += r.group(group); + } + else { + std::cerr << "Not implemented"; + } + } + else if next* == '@' { + next++; + + if next* == '-' || next* == '+' { + i := 0; + while i < cpp2::unchecked_narrow(r.group_number()) next i++ { + pos := 0; + if next* == '-' { + pos = r.group_start(i); + } + else { + pos = r.group_end(i); + } + result += std::to_string(pos); + } + next++; + } + else { + std::cerr << "Not implemented"; + } + } + else { + std::cerr << "Not implemented."; + } + } + iter = next; + } + + return result; +} + +sanitize: (copy str: std::string) -> std::string = +{ + str = cpp2::string_util::replace_all(str, "\a", "\\a"); + str = cpp2::string_util::replace_all(str, "\f", "\\f"); + str = cpp2::string_util::replace_all(str, "\x1b", "\\e"); + str = cpp2::string_util::replace_all(str, "\n", "\\n"); + str = cpp2::string_util::replace_all(str, "\r", "\\r"); + str = cpp2::string_util::replace_all(str, "\t", "\\t"); + + return str; +} + +test: (regex: M, id: std::string, regex_str: std::string, str: std::string, kind: std::string, resultExpr: std::string, + resultExpected: std::string) = { + + warning: std::string = ""; + if regex.to_string() != regex_str { + warning = "Warning: Parsed regex does not match."; + } + + status: std::string = "OK"; + + r := regex.search(str); + + if "y" == kind || "yM" == kind || "yS" == kind || "yB" == kind { + if !r.matched { + status = "Failure: Regex should apply."; + } + else { + // Have a match check the result + + result := create_result(resultExpr, r); + + if result != resultExpected { + status = "Failure: Result is wrong. (is: (sanitize(result))$)"; + } + } + } + else if "n" == kind { + if r.matched { + status = "Failure: Regex should not apply. Result is '(r.group(0))$'"; + } + } else { + status = "Unknown kind '(kind)$'"; + } + + if !warning.empty() { + warning += " "; + } + std::cout << "(id)$_(kind)$: (status)$ (warning)$regex: (regex_str)$ parsed_regex: (regex.to_string())$ str: (sanitize(str))$ result_expr: (resultExpr)$ expected_results (sanitize(resultExpected))$" << std::endl; +} + + +test_tests_20_lookbehind: @regex type = { + regex_01 := R"((?<=a)b)"; + regex_02 := R"((?<=af?)b)"; + regex_03 := R"((?<=a)b)"; + regex_04 := R"((?<=a(?:fo)?)b)"; + regex_05 := R"((?<=a)b)"; + regex_06 := R"((?<=a(?:foo)?)b)"; + regex_07 := R"((?)foo)"; + regex_50 := R"((?)foo)"; + regex_51 := R"((?<=bar>ABC)foo)"; + regex_52 := R"((?ABC)foo)"; + regex_53 := R"((?<=abcd(?<=(aaaabcd))))"; + regex_54 := R"((?=xy(?<=(aaxy))))"; + regex_55 := R"((?=xy(?<=(aaxyz?))))"; + regex_56 := R"((?<=(?=(aaxy))aa))"; + run: (this) = { + std::cout << "Running tests_20_lookbehind:"<< std::endl; + test(regex_01, "01", R"((?<=a)b)", "ab", "y", R"($&)", "b"); + test(regex_02, "02", R"((?<=af?)b)", "ab", "y", R"($&)", "b"); + test(regex_03, "03", R"((?<=a)b)", "cb", "n", R"(-)", "-"); + test(regex_04, "04", R"((?<=a(?:fo)?)b)", "cb", "n", R"(-)", "-"); + test(regex_05, "05", R"((?<=a)b)", "b", "n", R"(-)", "-"); + test(regex_06, "06", R"((?<=a(?:foo)?)b)", "b", "n", R"(-)", "-"); + test(regex_07, "07", R"((?)foo)", "bar>foo", "y", R"($&)", "foo"); + test(regex_50, "50", R"((?)foo)", "bar>foo", "n", R"(-)", "-"); + test(regex_51, "51", R"((?<=bar>ABC)foo)", "bar>ABCfoo", "y", R"($&)", "foo"); + test(regex_52, "52", R"((?ABC)foo)", "bar>ABCfoo", "n", R"(-)", "-"); + test(regex_53, "53", R"((?<=abcd(?<=(aaaabcd))))", "..aaaabcd..", "y", R"($1)", "aaaabcd"); + test(regex_54, "54", R"((?=xy(?<=(aaxy))))", "..aaxy..", "y", R"($1)", "aaxy"); + test(regex_55, "55", R"((?=xy(?<=(aaxyz?))))", "..aaxy..", "y", R"($1)", "aaxy"); + test(regex_56, "56", R"((?<=(?=(aaxy))aa))", "..aaxy..", "y", R"($1)", "aaxy"); + std::cout << std::endl; + } +} +main: () = { + test_tests_20_lookbehind().run(); +} From eff33c2797635dd4df296911f2b73403c0e705f8 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 8 Aug 2025 11:22:19 +0200 Subject: [PATCH 02/54] Fix for name lookup issues with MSVC. --- include/cpp2regex.h | 20 ++++++++++---------- include/cpp2regex.h2 | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/cpp2regex.h b/include/cpp2regex.h index e2a69946c..146372422 100644 --- a/include/cpp2regex.h +++ b/include/cpp2regex.h @@ -261,10 +261,10 @@ template [[nodiscard]] auto make_ #line 184 "cpp2regex.h2" // Helpers for creating wrappers of the iterators. // -template [[nodiscard]] auto make_forward_iterator(Iter const& pos) -> auto; -template [[nodiscard]] auto make_forward_iterator(std::reverse_iterator const& pos) -> auto; -template [[nodiscard]] auto make_reverse_iterator(Iter const& pos) -> auto; -template [[nodiscard]] auto make_reverse_iterator(std::reverse_iterator const& pos) -> auto; +template [[nodiscard]] auto cpp2_make_forward_iterator(Iter const& pos) -> auto; +template [[nodiscard]] auto cpp2_make_forward_iterator(std::reverse_iterator const& pos) -> auto; +template [[nodiscard]] auto cpp2_make_reverse_iterator(Iter const& pos) -> auto; +template [[nodiscard]] auto cpp2_make_reverse_iterator(std::reverse_iterator const& pos) -> auto; #line 192 "cpp2regex.h2" // End function that returns a valid match. @@ -927,13 +927,13 @@ template [[nodiscard]] auto make_ } #line 186 "cpp2regex.h2" -template [[nodiscard]] auto make_forward_iterator(Iter const& pos) -> auto { return pos; } +template [[nodiscard]] auto cpp2_make_forward_iterator(Iter const& pos) -> auto { return pos; } #line 187 "cpp2regex.h2" -template [[nodiscard]] auto make_forward_iterator(std::reverse_iterator const& pos) -> auto { return CPP2_UFCS(base)(pos); } +template [[nodiscard]] auto cpp2_make_forward_iterator(std::reverse_iterator const& pos) -> auto { return CPP2_UFCS(base)(pos); } #line 188 "cpp2regex.h2" -template [[nodiscard]] auto make_reverse_iterator(Iter const& pos) -> auto { return std::make_reverse_iterator(pos); } +template [[nodiscard]] auto cpp2_make_reverse_iterator(Iter const& pos) -> auto { return std::make_reverse_iterator(pos); } #line 189 "cpp2regex.h2" -template [[nodiscard]] auto make_reverse_iterator(std::reverse_iterator const& pos) -> auto { return pos; } +template [[nodiscard]] auto cpp2_make_reverse_iterator(std::reverse_iterator const& pos) -> auto { return pos; } #line 196 "cpp2regex.h2" [[nodiscard]] auto true_end_func::operator()(auto const& cur, auto& ctx) const& -> decltype(auto) { return ctx.pass(cur); } @@ -1153,7 +1153,7 @@ template [[nodiscard]] auto line_start_toke #line 575 "cpp2regex.h2" template [[nodiscard]] auto lookahead_token_matcher(auto const& cur, auto& ctx, auto const& func) -> bool { - auto r {func(make_forward_iterator(cur), make_forward_match_context(ctx), true_end_func())}; + auto r {func(cpp2_make_forward_iterator(cur), make_forward_match_context(ctx), true_end_func())}; if (!(positive)) { r.matched = !(r.matched); } @@ -1164,7 +1164,7 @@ template [[nodiscard]] auto lookahead_token_match #line 589 "cpp2regex.h2" template [[nodiscard]] auto lookbehind_token_matcher(auto const& cur, auto& ctx, auto const& func) -> bool { - auto r {func(make_reverse_iterator(cur), make_reverse_match_context(ctx), true_end_func())}; + auto r {func(cpp2_make_reverse_iterator(cur), make_reverse_match_context(ctx), true_end_func())}; if (!(positive)) { r.matched = !(r.matched); } diff --git a/include/cpp2regex.h2 b/include/cpp2regex.h2 index 763c5638b..6fbc03f12 100644 --- a/include/cpp2regex.h2 +++ b/include/cpp2regex.h2 @@ -183,10 +183,10 @@ make_reverse_match_context: (inout ctx: reverse_m // Helpers for creating wrappers of the iterators. // -make_forward_iterator: (pos: Iter) -> _ = pos; -make_forward_iterator: (pos: std::reverse_iterator) -> _ = pos.base(); -make_reverse_iterator: (pos: Iter) -> _ = std::make_reverse_iterator(pos); -make_reverse_iterator: (pos: std::reverse_iterator) -> _ = pos; +cpp2_make_forward_iterator: (pos: Iter) -> _ = pos; +cpp2_make_forward_iterator: (pos: std::reverse_iterator) -> _ = pos.base(); +cpp2_make_reverse_iterator: (pos: Iter) -> _ = std::make_reverse_iterator(pos); +cpp2_make_reverse_iterator: (pos: std::reverse_iterator) -> _ = pos; // End function that returns a valid match. @@ -574,7 +574,7 @@ line_start_token_matcher: (cur, inout ctx) -> bool // lookahead_token_matcher: (cur, inout ctx, func) -> bool = { - r := func(make_forward_iterator(cur), make_forward_match_context(ctx), true_end_func()); + r := func(cpp2_make_forward_iterator(cur), make_forward_match_context(ctx), true_end_func()); if !positive { r.matched = !r.matched; } @@ -588,7 +588,7 @@ lookahead_token_matcher: (cur, inout ctx, func) -> bool // lookbehind_token_matcher: (cur, inout ctx, func) -> bool = { - r := func(make_reverse_iterator(cur), make_reverse_match_context(ctx), true_end_func()); + r := func(cpp2_make_reverse_iterator(cur), make_reverse_match_context(ctx), true_end_func()); if !positive { r.matched = !r.matched; } From bb405b6c0f52fbb662693bc8f74f234e3ec24edb Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 8 Aug 2025 11:25:34 +0200 Subject: [PATCH 03/54] Add missing files. --- .../pure2-regex_20_lookbehind.cpp.execution | 58 + .../pure2-regex_20_lookbehind.cpp | 8990 +++++++++++++++++ .../pure2-regex_20_lookbehind.cpp2.output | 2 + 3 files changed, 9050 insertions(+) create mode 100644 regression-tests/test-results/gcc-13-c++2b/pure2-regex_20_lookbehind.cpp.execution create mode 100644 regression-tests/test-results/pure2-regex_20_lookbehind.cpp create mode 100644 regression-tests/test-results/pure2-regex_20_lookbehind.cpp2.output diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-regex_20_lookbehind.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-regex_20_lookbehind.cpp.execution new file mode 100644 index 000000000..cd61d4f56 --- /dev/null +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-regex_20_lookbehind.cpp.execution @@ -0,0 +1,58 @@ +Running tests_20_lookbehind: +01_y: OK regex: (?<=a)b parsed_regex: (?<=a)b str: ab result_expr: $& expected_results b +02_y: OK regex: (?<=af?)b parsed_regex: (?<=af?)b str: ab result_expr: $& expected_results b +03_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: cb result_expr: - expected_results - +04_n: OK regex: (?<=a(?:fo)?)b parsed_regex: (?<=a(?:fo)?)b str: cb result_expr: - expected_results - +05_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: b result_expr: - expected_results - +06_n: OK regex: (?<=a(?:foo)?)b parsed_regex: (?<=a(?:foo)?)b str: b result_expr: - expected_results - +07_y: OK regex: (?)foo parsed_regex: (?<=bar>)foo str: bar>foo result_expr: $& expected_results foo +50_n: OK regex: (?)foo parsed_regex: (?)foo str: bar>foo result_expr: - expected_results - +51_y: OK regex: (?<=bar>ABC)foo parsed_regex: (?<=bar>ABC)foo str: bar>ABCfoo result_expr: $& expected_results foo +52_n: OK regex: (?ABC)foo parsed_regex: (?ABC)foo str: bar>ABCfoo result_expr: - expected_results - +53_y: OK regex: (?<=abcd(?<=(aaaabcd))) parsed_regex: (?<=abcd(?<=(aaaabcd))) str: ..aaaabcd.. result_expr: $1 expected_results aaaabcd +54_y: OK regex: (?=xy(?<=(aaxy))) parsed_regex: (?=xy(?<=(aaxy))) str: ..aaxy.. result_expr: $1 expected_results aaxy +55_y: OK regex: (?=xy(?<=(aaxyz?))) parsed_regex: (?=xy(?<=(aaxyz?))) str: ..aaxy.. result_expr: $1 expected_results aaxy +56_y: OK regex: (?<=(?=(aaxy))aa) parsed_regex: (?<=(?=(aaxy))aa) str: ..aaxy.. result_expr: $1 expected_results aaxy + diff --git a/regression-tests/test-results/pure2-regex_20_lookbehind.cpp b/regression-tests/test-results/pure2-regex_20_lookbehind.cpp new file mode 100644 index 000000000..674d9ada9 --- /dev/null +++ b/regression-tests/test-results/pure2-regex_20_lookbehind.cpp @@ -0,0 +1,8990 @@ + +#define CPP2_IMPORT_STD Yes +#include "cpp2regex.h" + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-regex_20_lookbehind.cpp2" + +#line 166 "pure2-regex_20_lookbehind.cpp2" +class test_tests_20_lookbehind; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-regex_20_lookbehind.cpp2" +[[nodiscard]] auto create_result(cpp2::impl::in resultExpr, auto const& r) -> std::string; + +#line 113 "pure2-regex_20_lookbehind.cpp2" +[[nodiscard]] auto sanitize(std::string str) -> std::string; + +#line 125 "pure2-regex_20_lookbehind.cpp2" +template auto test(M const& regex, cpp2::impl::in id, cpp2::impl::in regex_str, cpp2::impl::in str, cpp2::impl::in kind, cpp2::impl::in resultExpr, + cpp2::impl::in resultExpected) -> void; + +#line 166 "pure2-regex_20_lookbehind.cpp2" +class test_tests_20_lookbehind { + +#line 223 "pure2-regex_20_lookbehind.cpp2" + public: auto run() const& -> void; + public: template class regex_01_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_01_matcher() = default; + public: regex_01_matcher(regex_01_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_01_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_01 {}; public: template class regex_02_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_02_matcher() = default; + public: regex_02_matcher(regex_02_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_02_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_02 {}; public: template class regex_03_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_03_matcher() = default; + public: regex_03_matcher(regex_03_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_03_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_03 {}; public: template class regex_04_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_04_matcher() = default; + public: regex_04_matcher(regex_04_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_04_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_04 {}; public: template class regex_05_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_05_matcher() = default; + public: regex_05_matcher(regex_05_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_05_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_05 {}; public: template class regex_06_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_06_matcher() = default; + public: regex_06_matcher(regex_06_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_06_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_06 {}; public: template class regex_07_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_07_matcher() = default; + public: regex_07_matcher(regex_07_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_07_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_07 {}; public: template class regex_08_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_08_matcher() = default; + public: regex_08_matcher(regex_08_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_08_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_08 {}; public: template class regex_09_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_09_matcher() = default; + public: regex_09_matcher(regex_09_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_09_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_09 {}; public: template class regex_10_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_10_matcher() = default; + public: regex_10_matcher(regex_10_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_10_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_10 {}; public: template class regex_11_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_11_matcher() = default; + public: regex_11_matcher(regex_11_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_11_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_11 {}; public: template class regex_12_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_12_matcher() = default; + public: regex_12_matcher(regex_12_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_12_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_12 {}; public: template class regex_13_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_13_matcher() = default; + public: regex_13_matcher(regex_13_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_13_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_13 {}; public: template class regex_14_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_14_matcher() = default; + public: regex_14_matcher(regex_14_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_14_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_14 {}; public: template class regex_15_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_15_matcher() = default; + public: regex_15_matcher(regex_15_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_15_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_15 {}; public: template class regex_16_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_16_matcher() = default; + public: regex_16_matcher(regex_16_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_16_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_16 {}; public: template class regex_17_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_17_matcher() = default; + public: regex_17_matcher(regex_17_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_17_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_17 {}; public: template class regex_18_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_18_matcher() = default; + public: regex_18_matcher(regex_18_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_18_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_18 {}; public: template class regex_19_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_19_matcher() = default; + public: regex_19_matcher(regex_19_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_19_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_19 {}; public: template class regex_20_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_20_matcher() = default; + public: regex_20_matcher(regex_20_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_20_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_20 {}; public: template class regex_21_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_21_matcher() = default; + public: regex_21_matcher(regex_21_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_21_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_21 {}; public: template class regex_22_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_22_matcher() = default; + public: regex_22_matcher(regex_22_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_22_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_22 {}; public: template class regex_23_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_23_matcher() = default; + public: regex_23_matcher(regex_23_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_23_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_23 {}; public: template class regex_24_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_24_matcher() = default; + public: regex_24_matcher(regex_24_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_24_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_24 {}; public: template class regex_25_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_25_matcher() = default; + public: regex_25_matcher(regex_25_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_25_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_25 {}; public: template class regex_26_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_26_matcher() = default; + public: regex_26_matcher(regex_26_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_26_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_26 {}; public: template class regex_27_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_27_matcher() = default; + public: regex_27_matcher(regex_27_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_27_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_27 {}; public: template class regex_28_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_28_matcher() = default; + public: regex_28_matcher(regex_28_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_28_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_28 {}; public: template class regex_29_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_29_matcher() = default; + public: regex_29_matcher(regex_29_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_29_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_29 {}; public: template class regex_30_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_30_matcher() = default; + public: regex_30_matcher(regex_30_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_30_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_30 {}; public: template class regex_31_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_31_matcher() = default; + public: regex_31_matcher(regex_31_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_31_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_31 {}; public: template class regex_32_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_32_matcher() = default; + public: regex_32_matcher(regex_32_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_32_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_32 {}; public: template class regex_33_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_33_matcher() = default; + public: regex_33_matcher(regex_33_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_33_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_33 {}; public: template class regex_34_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_34_matcher() = default; + public: regex_34_matcher(regex_34_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_34_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_34 {}; public: template class regex_35_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_35_matcher() = default; + public: regex_35_matcher(regex_35_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_35_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_35 {}; public: template class regex_36_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_36_matcher() = default; + public: regex_36_matcher(regex_36_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_36_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_36 {}; public: template class regex_37_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_37_matcher() = default; + public: regex_37_matcher(regex_37_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_37_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_37 {}; public: template class regex_38_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_38_matcher() = default; + public: regex_38_matcher(regex_38_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_38_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_38 {}; public: template class regex_39_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_5 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_6 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_39_matcher() = default; + public: regex_39_matcher(regex_39_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_39_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_39 {}; public: template class regex_40_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_40_matcher() = default; + public: regex_40_matcher(regex_40_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_40_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_40 {}; public: template class regex_41_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_41_matcher() = default; + public: regex_41_matcher(regex_41_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_41_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_41 {}; public: template class regex_42_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_42_matcher() = default; + public: regex_42_matcher(regex_42_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_42_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_42 {}; public: template class regex_43_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_43_matcher() = default; + public: regex_43_matcher(regex_43_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_43_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_43 {}; public: template class regex_44_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_44_matcher() = default; + public: regex_44_matcher(regex_44_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_44_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_44 {}; public: template class regex_45_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_45_matcher() = default; + public: regex_45_matcher(regex_45_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_45_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_45 {}; public: template class regex_46_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_46_matcher() = default; + public: regex_46_matcher(regex_46_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_46_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_46 {}; public: template class regex_47_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_47_matcher() = default; + public: regex_47_matcher(regex_47_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_47_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_47 {}; public: template class regex_48_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_48_matcher() = default; + public: regex_48_matcher(regex_48_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_48_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_48 {}; public: template class regex_49_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_49_matcher() = default; + public: regex_49_matcher(regex_49_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_49_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_49 {}; public: template class regex_50_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_50_matcher() = default; + public: regex_50_matcher(regex_50_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_50_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_50 {}; public: template class regex_51_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_51_matcher() = default; + public: regex_51_matcher(regex_51_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_51_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_51 {}; public: template class regex_52_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_52_matcher() = default; + public: regex_52_matcher(regex_52_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_52_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_52 {}; public: template class regex_53_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_53_matcher() = default; + public: regex_53_matcher(regex_53_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_53_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_53 {}; public: template class regex_54_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_54_matcher() = default; + public: regex_54_matcher(regex_54_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_54_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_54 {}; public: template class regex_55_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_3 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_4 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_55_matcher() = default; + public: regex_55_matcher(regex_55_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_55_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_55 {}; public: template class regex_56_matcher { + public: template using context = cpp2::regex::match_context; +public: class func_2 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_1 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: class func_0 { + public: template [[nodiscard]] auto operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return; + + }; + + public: template [[nodiscard]] static auto entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return; + + public: [[nodiscard]] static auto get_named_group_index(auto const& name) -> int; + + public: [[nodiscard]] constexpr static auto is_start_match() -> bool; +public: [[nodiscard]] static auto to_string() -> std::string; + + public: regex_56_matcher() = default; + public: regex_56_matcher(regex_56_matcher const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(regex_56_matcher const&) -> void = delete; + + }; + + public: cpp2::regex::regular_expression> regex_56 {}; + public: test_tests_20_lookbehind() = default; + public: test_tests_20_lookbehind(test_tests_20_lookbehind const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(test_tests_20_lookbehind const&) -> void = delete; + + +#line 283 "pure2-regex_20_lookbehind.cpp2" +}; +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-regex_20_lookbehind.cpp2" +[[nodiscard]] auto create_result(cpp2::impl::in resultExpr, auto const& r) -> std::string{ +#line 2 "pure2-regex_20_lookbehind.cpp2" + std::string result {""}; + + auto get_next {[_0 = (&resultExpr)](auto const& iter) mutable -> auto{ + auto start {std::distance(CPP2_UFCS(cbegin)((*cpp2::impl::assert_not_null(_0))), iter)}; + auto firstDollar {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(_0)), "$", start)}; + auto firstAt {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(_0)), "@", cpp2::move(start))}; + + auto end {std::min(cpp2::move(firstDollar), cpp2::move(firstAt))}; + if (end != std::string::npos) { + return CPP2_UFCS(cbegin)((*cpp2::impl::assert_not_null(_0))) + cpp2::move(end); + } + else { + return CPP2_UFCS(cend)((*cpp2::impl::assert_not_null(_0))); + } + }}; + auto extract_group_and_advance {[](auto& iter) -> auto{ + auto start {iter}; + + for( ; std::isdigit(*cpp2::impl::assert_not_null(iter)); ++iter ) {} + + return std::stoi(std::string(cpp2::move(start), iter)); + }}; + auto extract_until {[](auto& iter, cpp2::impl::in to) -> auto{ + auto start {iter}; + + for( ; (to != *cpp2::impl::assert_not_null(iter)); ++iter ) {}// TODO: Without bracket: error: postfix unary * (dereference) cannot be immediately followed by a (, identifier, or literal - add whitespace before * here if you meant binary * (multiplication) + + return std::string(cpp2::move(start), iter); + }}; + + auto iter {CPP2_UFCS(begin)(resultExpr)}; + + while( iter != CPP2_UFCS(end)(resultExpr) ) { + auto next {get_next(iter)}; + + if (next != iter) { + result += std::string(iter, next); + } + if (next != CPP2_UFCS(end)(resultExpr)) { + if (*cpp2::impl::assert_not_null(next) == '$') { + ++next; + + if (*cpp2::impl::assert_not_null(next) == '&') { + ++next; + result += CPP2_UFCS(group)(r, 0); + } + else {if (*cpp2::impl::assert_not_null(next) == '-' || *cpp2::impl::assert_not_null(next) == '+') { + auto is_start {*cpp2::impl::assert_not_null(next) == '-'}; + ++next; + if (*cpp2::impl::assert_not_null(next) == '{') { + ++next; // Skip { + auto group {extract_until(next, '}')}; + ++next; // Skip } + result += CPP2_UFCS(group)(r, cpp2::move(group)); + } + else {if (*cpp2::impl::assert_not_null(next) == '[') { + ++next; // Skip [ + auto group {extract_group_and_advance(next)}; + ++next; // Skip ] + + if (cpp2::move(is_start)) { + result += std::to_string(CPP2_UFCS(group_start)(r, cpp2::move(group))); + } + else { + result += std::to_string(CPP2_UFCS(group_end)(r, cpp2::move(group))); + } + } + else { + // Return max group + result += CPP2_UFCS(group)(r, CPP2_UFCS(group_number)(r) - 1); + }} + } + else {if (std::isdigit(*cpp2::impl::assert_not_null(next))) { + auto group {extract_group_and_advance(next)}; + result += CPP2_UFCS(group)(r, cpp2::move(group)); + } + else { + std::cerr << "Not implemented"; + }}} + } + else {if (*cpp2::impl::assert_not_null(next) == '@') { + ++next; + + if (*cpp2::impl::assert_not_null(next) == '-' || *cpp2::impl::assert_not_null(next) == '+') { + auto i {0}; + for( ; cpp2::impl::cmp_less(i,cpp2::unchecked_narrow(CPP2_UFCS(group_number)(r))); ++i ) { + auto pos {0}; + if (*cpp2::impl::assert_not_null(next) == '-') { + pos = CPP2_UFCS(group_start)(r, i); + } + else { + pos = CPP2_UFCS(group_end)(r, i); + } + result += std::to_string(cpp2::move(pos)); + } + ++next; + } + else { + std::cerr << "Not implemented"; + } + } + else { + std::cerr << "Not implemented."; + }} + } + iter = cpp2::move(next); + } + + return result; +} + +#line 113 "pure2-regex_20_lookbehind.cpp2" +[[nodiscard]] auto sanitize(std::string str) -> std::string +{ + str = cpp2::string_util::replace_all(str, "\a", "\\a"); + str = cpp2::string_util::replace_all(str, "\f", "\\f"); + str = cpp2::string_util::replace_all(str, "\x1b", "\\e"); + str = cpp2::string_util::replace_all(str, "\n", "\\n"); + str = cpp2::string_util::replace_all(str, "\r", "\\r"); + str = cpp2::string_util::replace_all(str, "\t", "\\t"); + + return cpp2::move(str); +} + +#line 125 "pure2-regex_20_lookbehind.cpp2" +template auto test(M const& regex, cpp2::impl::in id, cpp2::impl::in regex_str, cpp2::impl::in str, cpp2::impl::in kind, cpp2::impl::in resultExpr, + cpp2::impl::in resultExpected) -> void{ + + std::string warning {""}; + if (CPP2_UFCS(to_string)(regex) != regex_str) { + warning = "Warning: Parsed regex does not match."; + } + + std::string status {"OK"}; + + auto r {CPP2_UFCS(search)(regex, str)}; + + if ("y" == kind || "yM" == kind || "yS" == kind || "yB" == kind) { + if (!(r.matched)) { + status = "Failure: Regex should apply."; + } + else { + // Have a match check the result + + auto result {create_result(resultExpr, cpp2::move(r))}; + + if (result != resultExpected) { + status = "Failure: Result is wrong. (is: " + cpp2::to_string(sanitize(cpp2::move(result))) + ")"; + } + } + } + else {if ("n" == kind) { + if (r.matched) { + status = "Failure: Regex should not apply. Result is '" + cpp2::to_string(CPP2_UFCS(group)(cpp2::move(r), 0)) + "'"; + } + }else { + status = "Unknown kind '" + cpp2::to_string(kind) + "'"; + }} + + if (!(CPP2_UFCS(empty)(warning))) { + warning += " "; + } + std::cout << "" + cpp2::to_string(id) + "_" + cpp2::to_string(kind) + ": " + cpp2::to_string(cpp2::move(status)) + " " + cpp2::to_string(cpp2::move(warning)) + "regex: " + cpp2::to_string(regex_str) + " parsed_regex: " + cpp2::to_string(CPP2_UFCS(to_string)(regex)) + " str: " + cpp2::to_string(sanitize(str)) + " result_expr: " + cpp2::to_string(resultExpr) + " expected_results " + cpp2::to_string(sanitize(resultExpected)) + "" << std::endl; +} + +#line 223 "pure2-regex_20_lookbehind.cpp2" + auto test_tests_20_lookbehind::run() const& -> void{ + std::cout << "Running tests_20_lookbehind:" << std::endl; + test(regex_01, "01", R"((?<=a)b)", "ab", "y", R"($&)", "b"); + test(regex_02, "02", R"((?<=af?)b)", "ab", "y", R"($&)", "b"); + test(regex_03, "03", R"((?<=a)b)", "cb", "n", R"(-)", "-"); + test(regex_04, "04", R"((?<=a(?:fo)?)b)", "cb", "n", R"(-)", "-"); + test(regex_05, "05", R"((?<=a)b)", "b", "n", R"(-)", "-"); + test(regex_06, "06", R"((?<=a(?:foo)?)b)", "b", "n", R"(-)", "-"); + test(regex_07, "07", R"((?)foo)", "bar>foo", "y", R"($&)", "foo"); + test(regex_50, "50", R"((?)foo)", "bar>foo", "n", R"(-)", "-"); + test(regex_51, "51", R"((?<=bar>ABC)foo)", "bar>ABCfoo", "y", R"($&)", "foo"); + test(regex_52, "52", R"((?ABC)foo)", "bar>ABCfoo", "n", R"(-)", "-"); + test(regex_53, "53", R"((?<=abcd(?<=(aaaabcd))))", "..aaaabcd..", "y", R"($1)", "aaaabcd"); + test(regex_54, "54", R"((?=xy(?<=(aaxy))))", "..aaxy..", "y", R"($1)", "aaxy"); + test(regex_55, "55", R"((?=xy(?<=(aaxyz?))))", "..aaxy..", "y", R"($1)", "aaxy"); + test(regex_56, "56", R"((?<=(?=(aaxy))aa))", "..aaxy..", "y", R"($1)", "aaxy"); + std::cout << std::endl; + } + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_01_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_01_matcher::to_string() -> std::string{return R"((?<=a)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"f"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_02_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_02_matcher::to_string() -> std::string{return R"((?<=af?)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_03_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_03_matcher::to_string() -> std::string{return R"((?<=a)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"of"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 2;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_04_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_04_matcher::to_string() -> std::string{return R"((?<=a(?:fo)?)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_05_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_05_matcher::to_string() -> std::string{return R"((?<=a)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_06_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_06_matcher::to_string() -> std::string{return R"((?<=a(?:foo)?)b)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_07_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_07_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"boof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_08_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_08_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_09_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_09_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"aboof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),5)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,5); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 5;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_10_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_10_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_11_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_11_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"raboof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),6)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,6); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 6;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_12_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_12_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_13_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_13_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"braboof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 7;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_14_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_14_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_0 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_15_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_15_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"e"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_16_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_16_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_17_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_17_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_18_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_18_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_2(), cpp2::regex::no_reset(), other, func_3()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_19_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_19_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"d"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_4(), func_2(), cpp2::regex::no_reset(), func_3(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + + auto tmp_2_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; + static_cast(cpp2::move(tmp_2)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_3 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_20_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_20_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"d"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_4(), func_2(), cpp2::regex::no_reset(), func_3(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + + auto tmp_2_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; + static_cast(cpp2::move(tmp_2)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_21_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_21_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"dc"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 2;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_22_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_22_matcher::to_string() -> std::string{return R"((? template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + std::array str_tmp_0 {"a"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + ctx.set_group_start(1, r.pos); + + auto tmp_1_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_1 {cpp2::regex::make_on_return(cpp2::move(tmp_1_func))}; + static_cast(cpp2::move(tmp_1)); + if (!(cpp2::regex::line_start_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::line_end_token_matcher(r.pos, ctx))) {r.matched = false;break;} + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_23_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_23_matcher::to_string() -> std::string{return R"($(?<=^(a)))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_24_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_24_matcher::to_string() -> std::string{return R"((.*)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_25_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_25_matcher::to_string() -> std::string{return R"((.*)(?<=b))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_26_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_26_matcher::to_string() -> std::string{return R"((.*)(?<=b)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_27_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_27_matcher::to_string() -> std::string{return R"((.*)(?<=b|c))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_3 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_28_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_28_matcher::to_string() -> std::string{return R"((.*)(?<=b|c)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_29_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_29_matcher::to_string() -> std::string{return R"((.*)(?<=c|b))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_3 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_30_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_30_matcher::to_string() -> std::string{return R"((.*)(?<=c|b)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_31_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_31_matcher::to_string() -> std::string{return R"((.*)(?<=[bc]))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_32_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_32_matcher::to_string() -> std::string{return R"((.*)(?<=[bc])c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_33_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_33_matcher::to_string() -> std::string{return R"((.*?)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_34_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_34_matcher::to_string() -> std::string{return R"((.*?)(?<=b))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_35_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_35_matcher::to_string() -> std::string{return R"((.*?)(?<=b)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_36_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_36_matcher::to_string() -> std::string{return R"((.*?)(?<=b|c))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_3 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_37_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_37_matcher::to_string() -> std::string{return R"((.*?)(?<=b|c)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_38_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_38_matcher::to_string() -> std::string{return R"((.*?)(?<=c|b))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_5::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"b"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::alternative_token_matcher::match(r.pos, ctx, other, func_6(), func_4(), cpp2::regex::no_reset(), func_5(), cpp2::regex::no_reset()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_6::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_3 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_3, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_39_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_39_matcher::to_string() -> std::string{return R"((.*?)(?<=c|b)c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_40_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_40_matcher::to_string() -> std::string{return R"((.*?)(?<=[bc]))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + auto tmp_0_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_0 {cpp2::regex::make_on_return(cpp2::move(tmp_0_func))}; + static_cast(cpp2::move(tmp_0)); + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + + std::array str_tmp_1 {"c"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_41_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_41_matcher::to_string() -> std::string{return R"((.*?)(?<=[bc])c)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_42_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_42_matcher::to_string() -> std::string{return R"((?<=foo))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_43_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_43_matcher::to_string() -> std::string{return R"((?<=foo))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_44_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_44_matcher::to_string() -> std::string{return R"(.*(?<=foo))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_1(), cpp2::regex::no_reset(), other, func_2()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_3()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_45_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_45_matcher::to_string() -> std::string{return R"(.*(?<=foo))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"Y"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_46_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_46_matcher::to_string() -> std::string{return R"((?<=foo)Y)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"o"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_2 {"Y"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_47_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_47_matcher::to_string() -> std::string{return R"(o(?<=foo)Y)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::any_token_matcher(r.pos, ctx))) {r.matched = false;break;} + + std::array str_tmp_1 {"oof"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"X"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + if (!(cpp2::regex::class_token_matcher,::cpp2::regex::single_class_entry>::match(r.pos, ctx))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_48_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_48_matcher::to_string() -> std::string{return R"(X(?<=foo.)[YZ])"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {">rab"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"foo"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_49_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_49_matcher::to_string() -> std::string{return R"((?<=bar>)foo)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {">rab"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"foo"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_50_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_50_matcher::to_string() -> std::string{return R"((?)foo)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"CBA>rab"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 7;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"foo"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_51_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_51_matcher::to_string() -> std::string{return R"((?<=bar>ABC)foo)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"CBA>rab"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 7;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + + std::array str_tmp_1 {"foo"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),3)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,3); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 3;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_52_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_52_matcher::to_string() -> std::string{return R"((?ABC)foo)"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + std::array str_tmp_0 {"dcbaaaa"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),7)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,7); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 7;} + else {break;} + ctx.set_group_start(1, r.pos); + + auto tmp_1_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_1 {cpp2::regex::make_on_return(cpp2::move(tmp_1_func))}; + static_cast(cpp2::move(tmp_1)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} + + std::array str_tmp_2 {"dcba"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_53_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_53_matcher::to_string() -> std::string{return R"((?<=abcd(?<=(aaaabcd))))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + + std::array str_tmp_1 {"yxaa"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + ctx.set_group_start(1, r.pos); + + auto tmp_2_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; + static_cast(cpp2::move(tmp_2)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"xy"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 2;} + else {break;} + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_54_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_54_matcher::to_string() -> std::string{return R"((?=xy(?<=(aaxy))))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_3::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_1 {"z"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),1)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,1); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 1;} + else {break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_end(1, r.pos); + } + while ( + false + ); + if (r.matched) { + r = cpp2::regex::range_token_matcher::match(r.pos, ctx, func_3(), cpp2::regex::no_reset(), other, func_4()); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_4::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_2 {"yxaa"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_2, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + ctx.set_group_start(1, r.pos); + + auto tmp_3_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_3 {cpp2::regex::make_on_return(cpp2::move(tmp_3_func))}; + static_cast(cpp2::move(tmp_3)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"xy"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 2;} + else {break;} + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_55_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_55_matcher::to_string() -> std::string{return R"((?=xy(?<=(aaxyz?))))"; } + + + + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_2::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + ctx.set_group_start(1, r.pos); + + std::array str_tmp_1 {"aaxy"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),4)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,4); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_1, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 4;} + else {break;} + ctx.set_group_end(1, r.pos); + + auto tmp_2_func { +[&, _1 = (&r), _2 = (&ctx)]() mutable -> void{ + if (!((*cpp2::impl::assert_not_null(_1)).matched)) { + (*cpp2::impl::assert_not_null(_2)).set_group_invalid(1); + } + } + }; + + auto tmp_2 {cpp2::regex::make_on_return(cpp2::move(tmp_2_func))}; + static_cast(cpp2::move(tmp_2)); + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_1::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + + std::array str_tmp_0 {"aa"}; + if (cpp2::impl::cmp_less(std::distance(r.pos, ctx.end),2)) { + r.matched = false; + break; + } +{ +int i{0}; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + if (CPP2_ASSERT_IN_BOUNDS(str_tmp_0, i) != CPP2_ASSERT_IN_BOUNDS(r.pos, i)) {r.matched = false;} + } +} + if (r.matched) {r.pos += 2;} + else {break;} + if (!(cpp2::regex::lookahead_token_matcher(r.pos, ctx, func_2()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::func_0::operator()(Iter const& cur, auto&& ctx, auto const& other) const& -> cpp2::regex::match_return{ + + auto r {ctx.pass(cur)}; + do { + if (!(cpp2::regex::lookbehind_token_matcher(r.pos, ctx, func_1()))) {r.matched = false;break;} + } + while ( + false + ); + if (r.matched) { + r = other(r.pos, ctx); + } + else { + r.pos = ctx.end; + } + static_cast(CPP2_FORWARD(ctx)); + return r; + } + + template template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::entry(Iter const& cur, context& ctx) -> cpp2::regex::match_return{ + ctx.set_group_start(0, cur); + + auto r {func_0()(cur, ctx, cpp2::regex::true_end_func())}; + if (r.matched) {ctx.set_group_end(0, r.pos);} + return r; + } + + template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::get_named_group_index(auto const& name) -> int{ + static_cast(name); + return -1; + } + + template [[nodiscard]] constexpr auto test_tests_20_lookbehind::regex_56_matcher::is_start_match() -> bool { return false; } +template [[nodiscard]] auto test_tests_20_lookbehind::regex_56_matcher::to_string() -> std::string{return R"((?<=(?=(aaxy))aa))"; } + + +#line 284 "pure2-regex_20_lookbehind.cpp2" +auto main() -> int{ + CPP2_UFCS(run)(test_tests_20_lookbehind()); +} + diff --git a/regression-tests/test-results/pure2-regex_20_lookbehind.cpp2.output b/regression-tests/test-results/pure2-regex_20_lookbehind.cpp2.output new file mode 100644 index 000000000..4bb5f4259 --- /dev/null +++ b/regression-tests/test-results/pure2-regex_20_lookbehind.cpp2.output @@ -0,0 +1,2 @@ +pure2-regex_20_lookbehind.cpp2... ok (all Cpp2, passes safety checks) + From 5169cbfe197b68a3cceb7e7c7c93d904a1bb784f Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Sat, 9 Aug 2025 11:56:38 +0200 Subject: [PATCH 04/54] Refactor of autodiff with generalized traversal. Added test for autodiff. --- regression-tests/pure2-autodiff.cpp2 | 66 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 10 + .../test-results/pure2-autodiff.cpp | 280 ++ .../test-results/pure2-autodiff.cpp2.output | 252 ++ source/reflect.h | 2341 +++++++++++------ source/reflect.h2 | 922 +++++-- 6 files changed, 2750 insertions(+), 1121 deletions(-) create mode 100644 regression-tests/pure2-autodiff.cpp2 create mode 100644 regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution create mode 100644 regression-tests/test-results/pure2-autodiff.cpp create mode 100644 regression-tests/test-results/pure2-autodiff.cpp2.output diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 new file mode 100644 index 000000000..435d88620 --- /dev/null +++ b/regression-tests/pure2-autodiff.cpp2 @@ -0,0 +1,66 @@ + +ad_test: @autodiff @print type = { + + add_1: (x: double, y: double) -> (r: double) = { + r = x + y; + } + + add_2: (x: double, y: double) -> (r: double) = { + r = x + y + x; + } + + sub_1: (x: double, y: double) -> (r: double) = { + r = x - y; + } + + sub_2: (x: double, y: double) -> (r: double) = { + r = x - y - x; + } + + add_sub_2: (x: double, y: double) -> (r: double) = { + r = x + y - x; + } + + mul_1: (x: double, y: double) -> (r: double) = { + r = x * y; + } + + mul_2: (x: double, y: double) -> (r: double) = { + r = x * y * x; + } + + div_1: (x: double, y: double) -> (r: double) = { + r = x / y; + } + + div_2: (x: double, y: double) -> (r: double) = { + r = x / y / y; + } + + mul_div_2: (x: double, y: double) -> (r: double) = { + r = x * y / x; + } +} + +write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { + std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$) = (r = (ret.r)$, r_d = (ret.r_d)$)" << std::endl; +} + +main: () = { + + x: double = 2.0; + x_d: double = 1.0; + y: double = 3.0; + y_d: double = 2.0; + + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_diff(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_diff(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_diff(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_diff(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_diff(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_diff(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_diff(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); +} diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution new file mode 100644 index 000000000..462df5e61 --- /dev/null +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -0,0 +1,10 @@ +diff(x + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y + x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 7.000000, r_d = 4.000000) +diff(x - y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -1.000000, r_d = -1.000000) +diff(x - y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -3.000000, r_d = -2.000000) +diff(x + y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 6.000000, r_d = 7.000000) +diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 12.000000, r_d = 20.000000) +diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) +diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) +diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp new file mode 100644 index 000000000..dbaf35c5c --- /dev/null +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -0,0 +1,280 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-autodiff.cpp2" + +#line 2 "pure2-autodiff.cpp2" +class ad_test; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-autodiff.cpp2" + +#line 2 "pure2-autodiff.cpp2" +class ad_test { +using add_1_ret = double; + + +#line 4 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; +using add_2_ret = double; + + +#line 8 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; +using sub_1_ret = double; + + +#line 12 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; +using sub_2_ret = double; + + +#line 16 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; +using add_sub_2_ret = double; + + +#line 20 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; +using mul_1_ret = double; + + +#line 24 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; +using mul_2_ret = double; + + +#line 28 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; +using div_1_ret = double; + + +#line 32 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; +using div_2_ret = double; + + +#line 36 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; +using mul_div_2_ret = double; + + +#line 40 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; +struct add_1_diff_ret { double r; double r_d; }; + + + public: [[nodiscard]] static auto add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret; + +struct add_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret; + +struct sub_1_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret; + +struct sub_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret; + +struct add_sub_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret; + +struct mul_1_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret; + +struct mul_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret; + +struct div_1_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret; + +struct div_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret; + +struct mul_div_2_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret; + + public: ad_test() = default; + public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(ad_test const&) -> void = delete; + + +#line 43 "pure2-autodiff.cpp2" +}; + +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; + +#line 49 "pure2-autodiff.cpp2" +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-autodiff.cpp2" + +#line 4 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ + cpp2::impl::deferred_init r; +#line 5 "pure2-autodiff.cpp2" + r.construct(x + y); + return std::move(r.value()); } + +#line 8 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ + cpp2::impl::deferred_init r; +#line 9 "pure2-autodiff.cpp2" + r.construct(x + y + x); + return std::move(r.value()); } + +#line 12 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ + cpp2::impl::deferred_init r; +#line 13 "pure2-autodiff.cpp2" + r.construct(x - y); + return std::move(r.value()); } + +#line 16 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ + cpp2::impl::deferred_init r; +#line 17 "pure2-autodiff.cpp2" + r.construct(x - y - x); + return std::move(r.value()); } + +#line 20 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ + cpp2::impl::deferred_init r; +#line 21 "pure2-autodiff.cpp2" + r.construct(x + y - x); + return std::move(r.value()); } + +#line 24 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ + cpp2::impl::deferred_init r; +#line 25 "pure2-autodiff.cpp2" + r.construct(x * y); + return std::move(r.value()); } + +#line 28 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ + cpp2::impl::deferred_init r; +#line 29 "pure2-autodiff.cpp2" + r.construct(x * y * x); + return std::move(r.value()); } + +#line 32 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ + cpp2::impl::deferred_init r; +#line 33 "pure2-autodiff.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); + return std::move(r.value()); } + +#line 36 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ + cpp2::impl::deferred_init r; +#line 37 "pure2-autodiff.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); + return std::move(r.value()); } + +#line 40 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ + cpp2::impl::deferred_init r; +#line 41 "pure2-autodiff.cpp2" + r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); + return std::move(r.value()); } + + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d;r = x + y; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d + x_d;r = x + y + x; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d;r = x - y; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d - x_d;r = x - y - x; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d - x_d;r = x + y - x; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x * y_d + y * x_d;r = x * y; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x * y_d + y * x_d}; +auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d);r = cpp2::move(temp_1) * x; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; +auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x * y_d + y * x_d}; +auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); + return { std::move(r), std::move(r_d) }; + } + +#line 45 "pure2-autodiff.cpp2" +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ + std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; +} + +#line 49 "pure2-autodiff.cpp2" +auto main() -> int{ + + double x {2.0}; + double x_d {1.0}; + double y {3.0}; + double y_d {2.0}; + + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_diff(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_diff(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_diff(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_diff(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_diff(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_diff(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_diff(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); +} + diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output new file mode 100644 index 000000000..4c76146c3 --- /dev/null +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -0,0 +1,252 @@ +pure2-autodiff.cpp2... + +ad_test:/* @autodiff @print */ type = +{ + add_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y; + return; + } + + add_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y + x; + return; + } + + sub_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y; + return; + } + + sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y - x; + return; + } + + add_sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y - x; + return; + } + + mul_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y; + return; + } + + mul_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y * x; + return; + } + + div_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y; + return; + } + + div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y / y; + return; + } + + mul_div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y / x; + return; + } + + add_1_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } + + add_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d + y_d + x_d; + r = x + y + x; + return; + } + + sub_1_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d - y_d; + r = x - y; + return; + } + + sub_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d - y_d - x_d; + r = x - y - x; + return; + } + + add_sub_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d + y_d - x_d; + r = x + y - x; + return; + } + + mul_1_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x * y_d + y * x_d; + r = x * y; + return; + } + + mul_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x * y_d + y * x_d; + temp_1: _ = x * y; + r_d = temp_1 * x_d + x * temp_1_d; + r = temp_1 * x; + return; + } + + div_1_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d / y - x * y_d / (y * y); + r = x / y; + return; + } + + div_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x_d / y - x * y_d / (y * y); + temp_1: _ = x / y; + r_d = temp_1_d / y - temp_1 * y_d / (y * y); + r = temp_1 / y; + return; + } + + mul_div_2_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x * y_d + y * x_d; + temp_1: _ = x * y; + r_d = temp_1_d / x - temp_1 * x_d / (x * x); + r = temp_1 / x; + return; + } +} + ok (all Cpp2, passes safety checks) + diff --git a/source/reflect.h b/source/reflect.h index 97b5ced9e..7ab413ec9 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -99,80 +99,96 @@ class iteration_statement; #line 1902 "reflect.h2" class value_member_info; -#line 3199 "reflect.h2" -class autodiff_impl; +#line 2436 "reflect.h2" +class simple_traverser; -#line 3980 "reflect.h2" +#line 3715 "reflect.h2" +class autodiff_context; + + +#line 3724 "reflect.h2" +class autodiff_handler_base; + + +#line 3738 "reflect.h2" +class autodiff_expression_handler; + + +#line 3886 "reflect.h2" +class autodiff_stmt_handler; + + +#line 4362 "reflect.h2" class expression_flags; -#line 3996 "reflect.h2" +#line 4378 "reflect.h2" class regex_token; -#line 4023 "reflect.h2" +#line 4405 "reflect.h2" class regex_token_check; -#line 4044 "reflect.h2" +#line 4426 "reflect.h2" class regex_token_code; -#line 4065 "reflect.h2" +#line 4447 "reflect.h2" class regex_token_empty; -#line 4083 "reflect.h2" +#line 4465 "reflect.h2" class regex_token_list; -#line 4135 "reflect.h2" +#line 4517 "reflect.h2" class parse_context_group_state; -#line 4196 "reflect.h2" +#line 4578 "reflect.h2" class parse_context_branch_reset_state; -#line 4239 "reflect.h2" +#line 4621 "reflect.h2" class parse_context; -#line 4640 "reflect.h2" +#line 5022 "reflect.h2" class generation_function_context; -#line 4658 "reflect.h2" +#line 5040 "reflect.h2" class generation_context; -#line 4857 "reflect.h2" +#line 5239 "reflect.h2" class alternative_token; -#line 4872 "reflect.h2" +#line 5254 "reflect.h2" class alternative_token_gen; -#line 4937 "reflect.h2" +#line 5319 "reflect.h2" class any_token; -#line 4954 "reflect.h2" +#line 5336 "reflect.h2" class atomic_group_token; -#line 4984 "reflect.h2" +#line 5366 "reflect.h2" class char_token; -#line 5099 "reflect.h2" +#line 5481 "reflect.h2" class class_token; -#line 5323 "reflect.h2" +#line 5705 "reflect.h2" class group_ref_token; -#line 5460 "reflect.h2" +#line 5842 "reflect.h2" class group_token; -#line 5807 "reflect.h2" +#line 6189 "reflect.h2" class lookahead_lookbehind_token; -#line 5902 "reflect.h2" +#line 6284 "reflect.h2" class range_token; -#line 6059 "reflect.h2" +#line 6441 "reflect.h2" class special_range_token; -#line 6145 "reflect.h2" +#line 6527 "reflect.h2" template class regex_generator; -#line 6402 "reflect.h2" +#line 6784 "reflect.h2" } } @@ -1300,130 +1316,330 @@ auto noisy(cpp2::impl::in t) -> void; #line 2428 "reflect.h2" auto sample_print(cpp2::impl::in s, cpp2::impl::in indent) -> void; -#line 2447 "reflect.h2" -auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; +#line 2436 "reflect.h2" +class simple_traverser { + + public: virtual auto traverse(cpp2::impl::in expr) -> void; + +#line 2452 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; #line 2469 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2480 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2497 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2509 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2526 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2537 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2554 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2565 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2582 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2594 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2611 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2623 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2640 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2651 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2668 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2679 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2696 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2707 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2724 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2735 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2752 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2764 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; + +#line 2781 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in binexpr) -> void; + +#line 2792 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in isas) -> void; + +#line 2808 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in isas) -> void; + +#line 2819 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in exprs) -> void; + +#line 2826 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in prefix) -> void; + +#line 2842 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in prefix) -> void; + +#line 2847 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in postfix) -> void; + +#line 2863 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in postfix) -> void; + +#line 2882 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in uid) -> void; + +#line 2888 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in qid) -> void; + +#line 2898 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in tid) -> void; + +#line 2915 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in primary) -> void; + +#line 2935 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in idexpr) -> void; + public: simple_traverser() = default; + public: simple_traverser(simple_traverser const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(simple_traverser const&) -> void = delete; + + +#line 2950 "reflect.h2" +}; + +#line 2963 "reflect.h2" +auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; + +#line 2985 "reflect.h2" auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent = 0) -> void; -#line 2499 "reflect.h2" +#line 3015 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void; -#line 2509 "reflect.h2" +#line 3025 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 2519 "reflect.h2" +#line 3035 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 2538 "reflect.h2" +#line 3054 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 2585 "reflect.h2" +#line 3101 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 2602 "reflect.h2" +#line 3118 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 2612 "reflect.h2" +#line 3128 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 2644 "reflect.h2" +#line 3160 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void; -#line 2655 "reflect.h2" +#line 3171 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2685 "reflect.h2" +#line 3201 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2715 "reflect.h2" +#line 3231 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2745 "reflect.h2" +#line 3261 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2775 "reflect.h2" +#line 3291 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2805 "reflect.h2" +#line 3321 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2835 "reflect.h2" +#line 3351 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2865 "reflect.h2" +#line 3381 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2895 "reflect.h2" +#line 3411 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2925 "reflect.h2" +#line 3441 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2955 "reflect.h2" +#line 3471 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 2985 "reflect.h2" +#line 3501 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3015 "reflect.h2" +#line 3531 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void; -#line 3041 "reflect.h2" +#line 3557 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void; -#line 3056 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void; -#line 3080 "reflect.h2" +#line 3596 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void; -#line 3113 "reflect.h2" +#line 3629 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void; -#line 3124 "reflect.h2" +#line 3640 "reflect.h2" auto sample_traverser(cpp2::impl::in qid, cpp2::impl::in indent) -> void; -#line 3140 "reflect.h2" +#line 3656 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void; -#line 3157 "reflect.h2" +#line 3673 "reflect.h2" auto sample_traverser(cpp2::impl::in primary, cpp2::impl::in indent) -> void; -#line 3177 "reflect.h2" +#line 3693 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; -#line 3199 "reflect.h2" -class autodiff_impl { - +#line 3715 "reflect.h2" +class autodiff_context { private: int temporary_count {0}; + public: [[nodiscard]] auto gen_temporary() & -> std::string; + public: autodiff_context() = default; + public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_context const&) -> void = delete; + + +#line 3722 "reflect.h2" +}; + +class autodiff_handler_base { + public: autodiff_context* ctx; + public: std::string diff {""}; - public: [[nodiscard]] auto gen_temporary() & -> std::string; + public: autodiff_handler_base(autodiff_context* ctx_); +#line 3729 "reflect.h2" + public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; + +#line 3733 "reflect.h2" + public: auto append(autodiff_handler_base const& o) & -> void; + public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_handler_base const&) -> void = delete; + + +#line 3736 "reflect.h2" +}; + +class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { + +#line 3742 "reflect.h2" + public: using base = simple_traverser; + + public: std::string lhs; + + public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_); + +#line 3751 "reflect.h2" + public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; + +#line 3767 "reflect.h2" + public: auto traverse(cpp2::impl::in expr) -> void override; + +#line 3771 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3210 "reflect.h2" - public: [[nodiscard]] auto handle_expression_term([[maybe_unused]] auto& unnamed_param_2, auto const& term) & -> std::string; +#line 3775 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3222 "reflect.h2" - public: auto handle_expression_terms(auto& mf, cpp2::impl::in lhs, auto const& terms) & -> void; +#line 3779 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3515 "reflect.h2" +#line 3783 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3787 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3791 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3795 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3799 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3803 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3807 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3811 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3837 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 3881 "reflect.h2" + public: auto traverse(cpp2::impl::in isas) -> void override; + public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_expression_handler const&) -> void = delete; + + +#line 3884 "reflect.h2" +}; + +class autodiff_stmt_handler: public autodiff_handler_base { + +#line 3889 "reflect.h2" + public: autodiff_stmt_handler(autodiff_context* ctx_); + +#line 3893 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; - public: autodiff_impl() = default; - public: autodiff_impl(autodiff_impl const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(autodiff_impl const&) -> void = delete; + public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 3540 "reflect.h2" +#line 3921 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 3976 "reflect.h2" +#line 4358 "reflect.h2" using error_func = std::function x)>; -#line 3980 "reflect.h2" +#line 4362 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1458,20 +1674,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 3988 "reflect.h2" +#line 4370 "reflect.h2" }; -#line 3996 "reflect.h2" +#line 4378 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4004 "reflect.h2" +#line 4386 "reflect.h2" public: explicit regex_token(); -#line 4009 "reflect.h2" +#line 4391 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1483,103 +1699,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4015 "reflect.h2" +#line 4397 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4021 "reflect.h2" +#line 4403 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4027 "reflect.h2" +#line 4409 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4034 "reflect.h2" +#line 4416 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4038 "reflect.h2" +#line 4420 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4039 "reflect.h2" +#line 4421 "reflect.h2" }; -#line 4042 "reflect.h2" +#line 4424 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4048 "reflect.h2" +#line 4430 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4055 "reflect.h2" +#line 4437 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4059 "reflect.h2" +#line 4441 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4060 "reflect.h2" +#line 4442 "reflect.h2" }; -#line 4063 "reflect.h2" +#line 4445 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4069 "reflect.h2" +#line 4451 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4073 "reflect.h2" +#line 4455 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4077 "reflect.h2" +#line 4459 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4078 "reflect.h2" +#line 4460 "reflect.h2" }; -#line 4081 "reflect.h2" +#line 4463 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4087 "reflect.h2" +#line 4469 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4094 "reflect.h2" +#line 4476 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4100 "reflect.h2" +#line 4482 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4106 "reflect.h2" +#line 4488 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4114 "reflect.h2" +#line 4496 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1587,10 +1803,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4126 "reflect.h2" +#line 4508 "reflect.h2" }; -#line 4129 "reflect.h2" +#line 4511 "reflect.h2" // // Parse and generation context. // @@ -1606,33 +1822,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4149 "reflect.h2" +#line 4531 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4156 "reflect.h2" +#line 4538 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4168 "reflect.h2" +#line 4550 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4173 "reflect.h2" +#line 4555 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4177 "reflect.h2" +#line 4559 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4191 "reflect.h2" +#line 4573 "reflect.h2" }; -#line 4194 "reflect.h2" +#line 4576 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1645,25 +1861,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4212 "reflect.h2" +#line 4594 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4218 "reflect.h2" +#line 4600 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4225 "reflect.h2" +#line 4607 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4232 "reflect.h2" +#line 4614 "reflect.h2" }; -#line 4235 "reflect.h2" +#line 4617 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1679,7 +1895,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4251 "reflect.h2" +#line 4633 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1687,64 +1903,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4262 "reflect.h2" +#line 4644 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4275 "reflect.h2" +#line 4657 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4283 "reflect.h2" +#line 4665 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4287 "reflect.h2" +#line 4669 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4291 "reflect.h2" +#line 4673 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4303 "reflect.h2" +#line 4685 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4310 "reflect.h2" +#line 4692 "reflect.h2" public: auto next_alternative() & -> void; -#line 4316 "reflect.h2" +#line 4698 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4322 "reflect.h2" +#line 4704 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4326 "reflect.h2" +#line 4708 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4337 "reflect.h2" +#line 4719 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4341 "reflect.h2" +#line 4723 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4347 "reflect.h2" +#line 4729 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4351 "reflect.h2" +#line 4733 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4358 "reflect.h2" +#line 4740 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4369 "reflect.h2" +#line 4751 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1752,51 +1968,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4413 "reflect.h2" +#line 4795 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4425 "reflect.h2" +#line 4807 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4438 "reflect.h2" +#line 4820 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4461 "reflect.h2" +#line 4843 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4478 "reflect.h2" +#line 4860 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4499 "reflect.h2" +#line 4881 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 4509 "reflect.h2" +#line 4891 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 4513 "reflect.h2" +#line 4895 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 4569 "reflect.h2" +#line 4951 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 4608 "reflect.h2" +#line 4990 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 4623 "reflect.h2" +#line 5005 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -1808,10 +2024,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 4634 "reflect.h2" +#line 5016 "reflect.h2" }; -#line 4637 "reflect.h2" +#line 5019 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -1821,16 +2037,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 4651 "reflect.h2" +#line 5033 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 4654 "reflect.h2" +#line 5036 "reflect.h2" }; -#line 4657 "reflect.h2" +#line 5039 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -1850,68 +2066,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 4679 "reflect.h2" +#line 5061 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 4685 "reflect.h2" +#line 5067 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 4694 "reflect.h2" +#line 5076 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 4705 "reflect.h2" +#line 5087 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 4712 "reflect.h2" +#line 5094 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 4732 "reflect.h2" +#line 5114 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 4742 "reflect.h2" +#line 5124 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 4765 "reflect.h2" +#line 5147 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 4773 "reflect.h2" +#line 5155 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 4777 "reflect.h2" +#line 5159 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 4783 "reflect.h2" +#line 5165 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 4789 "reflect.h2" +#line 5171 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 4799 "reflect.h2" +#line 5181 "reflect.h2" public: auto finish_context() & -> void; -#line 4807 "reflect.h2" +#line 5189 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 4813 "reflect.h2" +#line 5195 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 4817 "reflect.h2" +#line 5199 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 4821 "reflect.h2" +#line 5203 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 4845 "reflect.h2" +#line 5227 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -1919,7 +2135,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 4851 "reflect.h2" +#line 5233 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -1939,27 +2155,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 4870 "reflect.h2" +#line 5252 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 4876 "reflect.h2" +#line 5258 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 4883 "reflect.h2" +#line 5265 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4900 "reflect.h2" +#line 5282 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4907 "reflect.h2" +#line 5289 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 4920 "reflect.h2" +#line 5302 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -1967,19 +2183,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 4932 "reflect.h2" +#line 5314 "reflect.h2" }; -#line 4935 "reflect.h2" +#line 5317 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 4941 "reflect.h2" +#line 5323 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 4945 "reflect.h2" +#line 5327 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -1987,7 +2203,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 4950 "reflect.h2" +#line 5332 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -1995,17 +2211,17 @@ class any_token class atomic_group_token : public regex_token { -#line 4958 "reflect.h2" +#line 5340 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 4969 "reflect.h2" +#line 5351 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4977 "reflect.h2" +#line 5359 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2013,7 +2229,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 4980 "reflect.h2" +#line 5362 "reflect.h2" }; // Regex syntax: a @@ -2021,34 +2237,34 @@ class atomic_group_token class char_token : public regex_token { -#line 4988 "reflect.h2" +#line 5370 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 4997 "reflect.h2" +#line 5379 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5003 "reflect.h2" +#line 5385 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5007 "reflect.h2" +#line 5389 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5030 "reflect.h2" +#line 5412 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5051 "reflect.h2" +#line 5433 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5069 "reflect.h2" +#line 5451 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5084 "reflect.h2" +#line 5466 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5090 "reflect.h2" +#line 5472 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2056,33 +2272,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5094 "reflect.h2" +#line 5476 "reflect.h2" }; -#line 5097 "reflect.h2" +#line 5479 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5103 "reflect.h2" +#line 5485 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5115 "reflect.h2" +#line 5497 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5241 "reflect.h2" +#line 5623 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5250 "reflect.h2" +#line 5632 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5255 "reflect.h2" +#line 5637 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2090,20 +2306,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5262 "reflect.h2" +#line 5644 "reflect.h2" }; -#line 5265 "reflect.h2" +#line 5647 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5306 "reflect.h2" +#line 5688 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5317 "reflect.h2" +#line 5699 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2113,20 +2329,20 @@ class class_token class group_ref_token : public regex_token { -#line 5327 "reflect.h2" +#line 5709 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5339 "reflect.h2" +#line 5721 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5440 "reflect.h2" +#line 5822 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5444 "reflect.h2" +#line 5826 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2134,10 +2350,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5447 "reflect.h2" +#line 5829 "reflect.h2" }; -#line 5450 "reflect.h2" +#line 5832 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2151,29 +2367,29 @@ class group_ref_token class group_token : public regex_token { -#line 5464 "reflect.h2" +#line 5846 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5486 "reflect.h2" +#line 5868 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5500 "reflect.h2" +#line 5882 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5659 "reflect.h2" +#line 6041 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5667 "reflect.h2" +#line 6049 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 5685 "reflect.h2" +#line 6067 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5716 "reflect.h2" +#line 6098 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2182,25 +2398,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 5723 "reflect.h2" +#line 6105 "reflect.h2" }; -#line 5726 "reflect.h2" +#line 6108 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 5767 "reflect.h2" +#line 6149 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 5787 "reflect.h2" +#line 6169 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 5803 "reflect.h2" +#line 6185 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2208,20 +2424,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 5811 "reflect.h2" +#line 6193 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 5820 "reflect.h2" +#line 6202 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5831 "reflect.h2" +#line 6213 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5838 "reflect.h2" +#line 6220 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2229,26 +2445,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 5841 "reflect.h2" +#line 6223 "reflect.h2" }; -#line 5844 "reflect.h2" +#line 6226 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 5872 "reflect.h2" +#line 6254 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 5900 "reflect.h2" +#line 6282 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 5906 "reflect.h2" +#line 6288 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2258,22 +2474,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5986 "reflect.h2" +#line 6368 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 5998 "reflect.h2" +#line 6380 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6011 "reflect.h2" +#line 6393 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6030 "reflect.h2" +#line 6412 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6040 "reflect.h2" +#line 6422 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6051 "reflect.h2" +#line 6433 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2281,16 +2497,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6054 "reflect.h2" +#line 6436 "reflect.h2" }; -#line 6057 "reflect.h2" +#line 6439 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6063 "reflect.h2" +#line 6445 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2299,7 +2515,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6093 "reflect.h2" +#line 6475 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2308,14 +2524,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6115 "reflect.h2" +#line 6497 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6137 "reflect.h2" +#line 6519 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2336,24 +2552,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6160 "reflect.h2" +#line 6542 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6195 "reflect.h2" +#line 6577 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6209 "reflect.h2" +#line 6591 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6221 "reflect.h2" +#line 6603 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6276 "reflect.h2" +#line 6658 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2364,7 +2580,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6402 "reflect.h2" +#line 6784 "reflect.h2" } } @@ -5306,135 +5522,676 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in << "\n"; } -#line 2437 "reflect.h2" -//----------------------------------------------------------------------- -// -// sample_traverser serves two purposes: -// -// - infrastructure for writing reflection API test cases -// -// - a sample for how code can use the reflection API, notably -// for reflecting on function bodies (statements, expressions) -// +#line 2438 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in expr) -> void + { + // An expression has other shortcuts to query deeper properties, + // but let's just traverse all the nested grammer elements to + // show how that traversal works -#line 2447 "reflect.h2" -auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void -{ - sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); + // The expressions use the pre_traverse function to decide which expression + // they are. The correct one calls traverse only once. - if (CPP2_UFCS(is_function)(decl)) { - sample_traverser(CPP2_UFCS(as_function)(decl), indent + 1); + // The expression's basic payload is just an assignment expression + pre_traverse(CPP2_UFCS(as_assignment_expression)(expr)); } - if (CPP2_UFCS(is_object)(decl)) { - sample_traverser(CPP2_UFCS(as_object)(decl), indent + 1); - } +#line 2452 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } - if (CPP2_UFCS(is_type)(decl)) { - sample_traverser(CPP2_UFCS(as_type)(decl), indent + 1); - } + // If this has only one term, it's not an actual assignment, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } - // ... - // ... extend as desired to namespace, alias, etc. - // ... -} + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } #line 2469 "reflect.h2" -auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent) -> void -{ - sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; - auto parameters {CPP2_UFCS(get_parameters)(f)}; - if (!(CPP2_UFCS(empty)(parameters))) { - sample_print("Parameters:", indent + 2); - for ( auto const& param : cpp2::move(parameters) ) { - sample_traverser(param, indent + 3); + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); } } - auto returns {CPP2_UFCS(get_returns)(f)}; - if (!(CPP2_UFCS(empty)(returns))) { - sample_print("Returns:", indent + 2); - for ( auto const& param : cpp2::move(returns) ) { - sample_traverser(param, indent + 3); +#line 2480 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual logical-or, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); } - } - sample_print("Body:", indent + 2); - if (!(CPP2_UFCS(has_compound_body)(f))) { - sample_traverser(CPP2_UFCS(get_body)(f), indent + 3); - } - else { - sample_traverser(CPP2_UFCS(get_compound_body)(f), indent + 3); + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } } -} -#line 2499 "reflect.h2" -auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void -{ - sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); - if (CPP2_UFCS(has_initializer)(o)) { - sample_print("Initializer:", indent + 1); - sample_traverser(CPP2_UFCS(get_initializer)(o), indent + 2); +#line 2497 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } } -} #line 2509 "reflect.h2" -auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void -{ - sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } - for ( auto const& m : CPP2_UFCS(get_members)(t) ) { - sample_traverser(m, indent + 1); + // If this has only one term, it's not an actual logical-and, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } } -} -#line 2519 "reflect.h2" -auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void -{ - sample_print("parameter:", indent); +#line 2526 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; - auto pass {CPP2_UFCS(get_passing_style)(t)}; - if (pass == passing_style::in) { sample_print("passing style: in", indent + 1);} - if (pass == passing_style::in_ref) { sample_print("passing style: in_ref", indent + 1);} - if (pass == passing_style::copy) { sample_print("passing style: copy", indent + 1);} - if (pass == passing_style::inout) { sample_print("passing style: inout", indent + 1);} - if (pass == passing_style::out) { sample_print("passing style: out", indent + 1);} - if (pass == passing_style::move) { sample_print("passing style: move", indent + 1);} - if (pass == passing_style::forward) { sample_print("passing style: forward", indent + 1);} - if (cpp2::move(pass) == passing_style::forward_ref) {sample_print("passing style: forward_ref", indent + 1); } + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } - sample_print("declaration:", indent + 1); - sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); -} +#line 2537 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } -#line 2538 "reflect.h2" -auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void -{ - if (CPP2_UFCS(is_expression_statement)(stmt)) { - sample_traverser(CPP2_UFCS(get_expression)(CPP2_UFCS(as_expression_statement)(stmt)), indent); - } + // If this has only one term, it's not an actual bit-or, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } - if (CPP2_UFCS(is_compound_statement)(stmt)) { - sample_traverser(CPP2_UFCS(as_compound_statement)(stmt), indent); + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } } - if (CPP2_UFCS(is_selection_statement)(stmt)) +#line 2554 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { - auto sel {CPP2_UFCS(as_selection_statement)(stmt)}; - sample_print("" + cpp2::to_string(CPP2_UFCS(get_identifier)(sel)) + " statement", indent); + auto terms {CPP2_UFCS(get_terms)(binexpr)}; - sample_print("condition:", indent + 1); - sample_traverser(CPP2_UFCS(get_expression)(sel), indent + 2); + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } - sample_print("true branch:", indent + 1); - sample_traverser(CPP2_UFCS(get_true_branch)(sel), indent + 2); +#line 2565 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } - if (CPP2_UFCS(has_false_branch)(sel)) { - sample_print("false branch:", indent + 1); - sample_traverser(CPP2_UFCS(get_false_branch)(cpp2::move(sel)), indent + 2); + // If this has only one term, it's not an actual bit-xor, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); } - } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2582 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2594 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual bit-and, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2611 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2623 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual equality, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2640 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2651 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual relational, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2668 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2679 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual compare, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2696 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2707 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual shift, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2724 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2735 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual additive, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2752 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2764 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(terms))) ) { cpp2::cpp2_default.report_violation(""); } + + // If this has only one term, it's not an actual multiplicative, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(ssize)(terms) == 1) { + pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(terms)))); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + +#line 2781 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void + { + auto terms {CPP2_UFCS(get_terms)(binexpr)}; + + for ( + auto const& term : cpp2::move(terms) ) + { + traverse(CPP2_UFCS(get_term)(term)); + } + } + +#line 2792 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in isas) -> void + { + auto terms {CPP2_UFCS(get_terms)(isas)}; + + // If this has no additional terms, it's not an actual is-as, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(empty)(cpp2::move(terms))) { + pre_traverse(CPP2_UFCS(get_expression)(isas)); + } + + // Else we're at an actual is-as expression with a rhs + else { + traverse(isas); + } + } + +#line 2808 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in isas) -> void + { + auto terms {CPP2_UFCS(get_terms)(isas)}; + + pre_traverse(CPP2_UFCS(get_expression)(isas)); + + for ( auto const& term : cpp2::move(terms) ) { + traverse(CPP2_UFCS(get_expr)(term)); + } + } + +#line 2819 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in exprs) -> void + { + for ( auto const& expr : CPP2_UFCS(get_expressions)(exprs) ) { + traverse(expr); + } + } + +#line 2826 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in prefix) -> void + { + auto ops {CPP2_UFCS(get_ops)(prefix)}; + + // If this has no additional ops, it's not a naked prefix expr, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(empty)(cpp2::move(ops))) { + pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); + } + + // Else we're at an actual prefix expression with ops + else { + traverse(prefix); + } + } + +#line 2842 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in prefix) -> void + { + pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); + } + +#line 2847 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in postfix) -> void + { + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + // If this has no additional terms, it's not a naked postfix expr, + // it's holding a lower grammar production so go traverse that + if (CPP2_UFCS(empty)(cpp2::move(terms))) { + traverse(CPP2_UFCS(get_primary_expression)(postfix)); + } + + // Else we're at an actual postfix expression with ops + else { + traverse(postfix); + } + } + +#line 2863 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in postfix) -> void + { + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + traverse(CPP2_UFCS(get_primary_expression)(postfix)); + + for ( auto const& term : cpp2::move(terms) ) { + if (CPP2_UFCS(is_id_expression)(term)) { + traverse(CPP2_UFCS(get_id_expression)(term)); + } + else {if (CPP2_UFCS(is_expression_list)(term)) { + traverse(CPP2_UFCS(get_expression_list)(term)); + } + else {if (CPP2_UFCS(is_expression)(term)) { + traverse(CPP2_UFCS(get_expression)(term)); + }}} + } + } + +#line 2882 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in uid) -> void + { + static_cast(uid); + } + +#line 2888 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in qid) -> void + { + for ( + auto const& term : CPP2_UFCS(get_terms)(qid) ) + { + traverse(CPP2_UFCS(get_unqualified)(term)); + } + } + +#line 2898 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in tid) -> void + { + if (CPP2_UFCS(is_postfix_expression)(tid)) { + traverse(CPP2_UFCS(as_postfix_expression)(tid)); + } + else {if (CPP2_UFCS(is_qualified_id)(tid)) { + traverse(CPP2_UFCS(as_qualified_id)(tid)); + } + else {if (CPP2_UFCS(is_unqualified_id)(tid)) { + traverse(CPP2_UFCS(as_unqualified_id)(tid)); + } + else { + // Regular type_id + }}} + } + +#line 2915 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in primary) -> void + { + if (CPP2_UFCS(is_identifier)(primary)) { + // Regular identifier + } + else {if (CPP2_UFCS(is_expression_list)(primary)) { + traverse(CPP2_UFCS(as_expression_list)(primary)); + } + else {if (CPP2_UFCS(is_literal)(primary)) { + // Regular literal + } + else {if (CPP2_UFCS(is_declaration)(primary)) { + // TODO: traverse(primary.as_declaration()); + } + else { + // Regular primary + }}}} + } + +#line 2935 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in idexpr) -> void + { + if (CPP2_UFCS(is_identifier)(idexpr)) { + // Regular id + } + else {if (CPP2_UFCS(is_qualified)(idexpr)) { + traverse(CPP2_UFCS(as_qualified)(idexpr)); + } + else {if (CPP2_UFCS(is_unqualified)(idexpr)) { + traverse(CPP2_UFCS(as_unqualified)(idexpr)); + } + else { + // Regular id expr + }}} + } + +#line 2953 "reflect.h2" +//----------------------------------------------------------------------- +// +// sample_traverser serves two purposes: +// +// - infrastructure for writing reflection API test cases +// +// - a sample for how code can use the reflection API, notably +// for reflecting on function bodies (statements, expressions) +// + +#line 2963 "reflect.h2" +auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void +{ + sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); + + if (CPP2_UFCS(is_function)(decl)) { + sample_traverser(CPP2_UFCS(as_function)(decl), indent + 1); + } + + if (CPP2_UFCS(is_object)(decl)) { + sample_traverser(CPP2_UFCS(as_object)(decl), indent + 1); + } + + if (CPP2_UFCS(is_type)(decl)) { + sample_traverser(CPP2_UFCS(as_type)(decl), indent + 1); + } + + // ... + // ... extend as desired to namespace, alias, etc. + // ... +} + +#line 2985 "reflect.h2" +auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent) -> void +{ + sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); + + auto parameters {CPP2_UFCS(get_parameters)(f)}; + if (!(CPP2_UFCS(empty)(parameters))) { + sample_print("Parameters:", indent + 2); + for ( auto const& param : cpp2::move(parameters) ) { + sample_traverser(param, indent + 3); + } + } + + auto returns {CPP2_UFCS(get_returns)(f)}; + if (!(CPP2_UFCS(empty)(returns))) { + sample_print("Returns:", indent + 2); + for ( auto const& param : cpp2::move(returns) ) { + sample_traverser(param, indent + 3); + } + } + + sample_print("Body:", indent + 2); + if (!(CPP2_UFCS(has_compound_body)(f))) { + sample_traverser(CPP2_UFCS(get_body)(f), indent + 3); + } + else { + sample_traverser(CPP2_UFCS(get_compound_body)(f), indent + 3); + } +} + +#line 3015 "reflect.h2" +auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void +{ + sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); + if (CPP2_UFCS(has_initializer)(o)) { + sample_print("Initializer:", indent + 1); + sample_traverser(CPP2_UFCS(get_initializer)(o), indent + 2); + } +} + +#line 3025 "reflect.h2" +auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void +{ + sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); + + for ( auto const& m : CPP2_UFCS(get_members)(t) ) { + sample_traverser(m, indent + 1); + } +} + +#line 3035 "reflect.h2" +auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void +{ + sample_print("parameter:", indent); + + auto pass {CPP2_UFCS(get_passing_style)(t)}; + if (pass == passing_style::in) { sample_print("passing style: in", indent + 1);} + if (pass == passing_style::in_ref) { sample_print("passing style: in_ref", indent + 1);} + if (pass == passing_style::copy) { sample_print("passing style: copy", indent + 1);} + if (pass == passing_style::inout) { sample_print("passing style: inout", indent + 1);} + if (pass == passing_style::out) { sample_print("passing style: out", indent + 1);} + if (pass == passing_style::move) { sample_print("passing style: move", indent + 1);} + if (pass == passing_style::forward) { sample_print("passing style: forward", indent + 1);} + if (cpp2::move(pass) == passing_style::forward_ref) {sample_print("passing style: forward_ref", indent + 1); } + + sample_print("declaration:", indent + 1); + sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); +} + +#line 3054 "reflect.h2" +auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void +{ + if (CPP2_UFCS(is_expression_statement)(stmt)) { + sample_traverser(CPP2_UFCS(get_expression)(CPP2_UFCS(as_expression_statement)(stmt)), indent); + } + + if (CPP2_UFCS(is_compound_statement)(stmt)) { + sample_traverser(CPP2_UFCS(as_compound_statement)(stmt), indent); + } + + if (CPP2_UFCS(is_selection_statement)(stmt)) + { + auto sel {CPP2_UFCS(as_selection_statement)(stmt)}; + sample_print("" + cpp2::to_string(CPP2_UFCS(get_identifier)(sel)) + " statement", indent); + + sample_print("condition:", indent + 1); + sample_traverser(CPP2_UFCS(get_expression)(sel), indent + 2); + + sample_print("true branch:", indent + 1); + sample_traverser(CPP2_UFCS(get_true_branch)(sel), indent + 2); + + if (CPP2_UFCS(has_false_branch)(sel)) { + sample_print("false branch:", indent + 1); + sample_traverser(CPP2_UFCS(get_false_branch)(cpp2::move(sel)), indent + 2); + } + } if (CPP2_UFCS(is_declaration)(stmt)) { sample_traverser(CPP2_UFCS(as_declaration)(stmt), indent + 1); @@ -5455,7 +6212,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in stmt, cpp2::impl::in indent) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -5472,7 +6229,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl: } } -#line 2602 "reflect.h2" +#line 3118 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { sample_print("return statement", indent); @@ -5482,7 +6239,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::i } } -#line 2612 "reflect.h2" +#line 3128 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -5514,7 +6271,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl } } -#line 2644 "reflect.h2" +#line 3160 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void { // An expression has other shortcuts to query deeper properties, @@ -5525,7 +6282,7 @@ auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5543,7 +6300,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 2671 "reflect.h2" +#line 3187 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5555,11 +6312,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2681 "reflect.h2" +#line 3197 "reflect.h2" } } -#line 2685 "reflect.h2" +#line 3201 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5577,7 +6334,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 2701 "reflect.h2" +#line 3217 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5589,11 +6346,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2711 "reflect.h2" +#line 3227 "reflect.h2" } } -#line 2715 "reflect.h2" +#line 3231 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5611,7 +6368,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2 { auto first{true}; -#line 2731 "reflect.h2" +#line 3247 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5623,11 +6380,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2741 "reflect.h2" +#line 3257 "reflect.h2" } } -#line 2745 "reflect.h2" +#line 3261 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5645,7 +6402,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::imp { auto first{true}; -#line 2761 "reflect.h2" +#line 3277 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5657,11 +6414,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2771 "reflect.h2" +#line 3287 "reflect.h2" } } -#line 2775 "reflect.h2" +#line 3291 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5679,7 +6436,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 2791 "reflect.h2" +#line 3307 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5691,11 +6448,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2801 "reflect.h2" +#line 3317 "reflect.h2" } } -#line 2805 "reflect.h2" +#line 3321 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5713,7 +6470,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 2821 "reflect.h2" +#line 3337 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5725,11 +6482,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2831 "reflect.h2" +#line 3347 "reflect.h2" } } -#line 2835 "reflect.h2" +#line 3351 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5747,7 +6504,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 2851 "reflect.h2" +#line 3367 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5759,11 +6516,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2861 "reflect.h2" +#line 3377 "reflect.h2" } } -#line 2865 "reflect.h2" +#line 3381 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5781,7 +6538,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 2881 "reflect.h2" +#line 3397 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5793,11 +6550,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2891 "reflect.h2" +#line 3407 "reflect.h2" } } -#line 2895 "reflect.h2" +#line 3411 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5815,7 +6572,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 2911 "reflect.h2" +#line 3427 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5827,11 +6584,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2921 "reflect.h2" +#line 3437 "reflect.h2" } } -#line 2925 "reflect.h2" +#line 3441 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5849,7 +6606,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl { auto first{true}; -#line 2941 "reflect.h2" +#line 3457 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5861,11 +6618,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2951 "reflect.h2" +#line 3467 "reflect.h2" } } -#line 2955 "reflect.h2" +#line 3471 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5883,7 +6640,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 2971 "reflect.h2" +#line 3487 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5895,11 +6652,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 2981 "reflect.h2" +#line 3497 "reflect.h2" } } -#line 2985 "reflect.h2" +#line 3501 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5917,7 +6674,7 @@ auto sample_traverser(cpp2::impl::in binexpr, c { auto first{true}; -#line 3001 "reflect.h2" +#line 3517 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -5929,11 +6686,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3011 "reflect.h2" +#line 3527 "reflect.h2" } } -#line 3015 "reflect.h2" +#line 3531 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -5959,7 +6716,7 @@ auto sample_traverser(cpp2::impl::in isas, cpp2::impl::i } } -#line 3041 "reflect.h2" +#line 3557 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_empty)(exprs)) { @@ -5974,7 +6731,7 @@ auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::i } } -#line 3056 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -5998,7 +6755,7 @@ auto sample_traverser(cpp2::impl::in prefix, cpp2::impl } } -#line 3080 "reflect.h2" +#line 3596 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6031,7 +6788,7 @@ auto sample_traverser(cpp2::impl::in postfix, cpp2::im } } -#line 3113 "reflect.h2" +#line 3629 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(uid)) { @@ -6042,13 +6799,13 @@ auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in qid, cpp2::impl::in indent) -> void { { auto first{true}; -#line 3127 "reflect.h2" +#line 3643 "reflect.h2" for ( auto const& term : CPP2_UFCS(get_terms)(qid) ) { @@ -6060,10 +6817,10 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_unqualified)(term), indent + 2); } } -#line 3137 "reflect.h2" +#line 3653 "reflect.h2" } -#line 3140 "reflect.h2" +#line 3656 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6080,7 +6837,7 @@ auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in primary, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6100,7 +6857,7 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im }}}} } -#line 3177 "reflect.h2" +#line 3693 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6117,327 +6874,205 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}} } -#line 3194 "reflect.h2" +#line 3710 "reflect.h2" //----------------------------------------------------------------------- // // autodiff - stub // -#line 3205 "reflect.h2" - [[nodiscard]] auto autodiff_impl::gen_temporary() & -> std::string{ +#line 3718 "reflect.h2" + [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 3210 "reflect.h2" - [[nodiscard]] auto autodiff_impl::handle_expression_term([[maybe_unused]] auto& unnamed_param_2, auto const& term) & -> std::string{/*mf*/ +#line 3729 "reflect.h2" + autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) + : ctx{ ctx_ }{ + +#line 3731 "reflect.h2" + } +#line 3729 "reflect.h2" + auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { + ctx = ctx_; + diff = ""; + return *this; + +#line 3731 "reflect.h2" + } + +#line 3733 "reflect.h2" + auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ + diff += o.diff; + } + +#line 3746 "reflect.h2" + autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_) + : simple_traverser{ } + , autodiff_handler_base{ ctx_ } + , lhs{ lhs_ }{ + +#line 3749 "reflect.h2" + } + +#line 3751 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); } else { - auto t {gen_temporary()}; std::cout << "Handle generation for: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + "" << std::endl; - //handle_expression_terms(mf, t, term..get_expression_list()); + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + autodiff_expression_handler ad {ctx, t}; + //ad..traverse(term..get_expression_list()); + + append(cpp2::move(ad)); + return t; } } -#line 3222 "reflect.h2" - auto autodiff_impl::handle_expression_terms(auto& mf, cpp2::impl::in lhs, auto const& terms) & -> void{ - // Handle binary || - auto logical_or_terms {terms}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(logical_or_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found as a grammatical - // identifier (this won't compile as Cpp1, but it will - // be visible via @print for development/debugging) - diff += "found_logical_or_with_____"; - auto count {0}; - for ( auto const& term : logical_or_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3767 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ + base::traverse(expr); + } - return ; - } +#line 3771 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); + } - // Handle binary && - if (CPP2_UFCS(ssize)(logical_or_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one logical or term here"); - } - auto logical_and_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(logical_or_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(logical_and_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_logical_and_with_____"; - auto count {0}; - for ( auto const& term : logical_and_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3775 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); + } - return ; - } +#line 3779 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); + } - // Handle binary | - if (CPP2_UFCS(ssize)(logical_and_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one logical and term here"); - } - auto bit_or_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(logical_and_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(bit_or_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_or_with_____"; - auto count {0}; - for ( auto const& term : bit_or_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3783 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); + } - return ; - } +#line 3787 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); + } - // Handle binary ^ - if (CPP2_UFCS(ssize)(bit_or_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one bit or term here"); - } - auto bit_xor_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(bit_or_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(bit_xor_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_xor_with_____"; - auto count {0}; - for ( auto const& term : bit_xor_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3791 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); + } - return ; - } +#line 3795 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); + } - // Handle binary & - if (CPP2_UFCS(ssize)(bit_xor_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one bit xor term here"); - } - auto bit_and_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(bit_xor_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(bit_and_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_and_with_____"; - auto count {0}; - for ( auto const& term : bit_and_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3799 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); + } - return ; - } +#line 3803 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); + } - // Handle binary == and != - if (CPP2_UFCS(ssize)(bit_and_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one bit and term here"); - } - auto equality_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(bit_and_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(equality_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_equality_with_____"; - auto count {0}; - for ( auto const& term : equality_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; +#line 3807 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); + } - return ; - } +#line 3811 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + auto terms {CPP2_UFCS(get_terms)(binexpr)}; - // Handle binary < > <= >= - if (CPP2_UFCS(ssize)(equality_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one equality term here"); - } - auto relational_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(equality_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(relational_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_relational_with_____"; - auto count {0}; - for ( auto const& term : relational_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; + auto first {true}; + std::string fwd {"" + cpp2::to_string(lhs) + "_d = "}; + std::string primal {"" + cpp2::to_string(lhs) + " = "}; + for ( auto const& term : cpp2::move(terms) ) { + if (!(first)) { + auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term))}; + fwd += " " + cpp2::to_string(op) + " "; + primal += " " + cpp2::to_string(cpp2::move(op)) + " "; } - diff += ";"; - - return ; - } - // Handle binary <=> - if (CPP2_UFCS(ssize)(relational_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one relational term here"); - } - auto compare_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(relational_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(compare_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_compare_with_____"; - auto count {0}; - for ( auto const& term : compare_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; + auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; + fwd += "" + cpp2::to_string(var) + "_d"; + primal += "" + cpp2::to_string(cpp2::move(var)) + ""; - return ; + first = false; } - // Handle binary << and >> - if (CPP2_UFCS(ssize)(compare_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one compare term here"); - } - auto shift_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(compare_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(shift_terms),1)) - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_shift_with_____"; - auto count {0}; - for ( auto const& term : shift_terms ) { - if (cpp2::impl::cmp_greater(++count,1)) { - diff += CPP2_UFCS(get_op)(term) + "___"; - } - diff += CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(term)) + "___"; - } - diff += ";"; + fwd += ";"; + primal += ";"; - return ; - } + diff += cpp2::move(fwd) + cpp2::move(primal); + } - // Handle binary + and - - if (CPP2_UFCS(ssize)(shift_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one shift term here"); - } - auto additive_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(shift_terms))))}; - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(additive_terms),1)) - { - auto first {true}; - std::string fwd {"" + cpp2::to_string(lhs) + "_d = "}; - std::string primal {"" + cpp2::to_string(lhs) + " = "}; - for ( auto const& term : additive_terms ) { - if (!(first)) { - auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term))}; - fwd += " " + cpp2::to_string(op) + " "; - primal += " " + cpp2::to_string(cpp2::move(op)) + " "; - } +#line 3837 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ + auto terms {CPP2_UFCS(get_terms)(binexpr)}; - auto var {handle_expression_term(mf, CPP2_UFCS(get_term)(term))}; - fwd += "" + cpp2::to_string(var) + "_d"; - primal += "" + cpp2::to_string(cpp2::move(var)) + ""; + auto arg_a {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; - first = false; - } + int i {1}; + for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(terms)); i += 1 ) { + auto arg_b {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; - fwd += ";"; - primal += ";"; + auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; - diff += cpp2::move(fwd) + cpp2::move(primal); + std::string fwd {""}; + std::string primal {""}; - return ; - } + if ("*" == op) { + fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a) + "_d"; + primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; + } + else {if ("/" == op) { + fwd = "" + cpp2::to_string(arg_a) + "_d / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; + } + else { + CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); + }} - // Handle binary * / % - if (CPP2_UFCS(ssize)(additive_terms) != 1) { - CPP2_UFCS(error)(mf, "ICE: there should be exactly one additive term here"); - } - auto multiplicative_terms {CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_UFCS(front)(cpp2::move(additive_terms))))}; +#line 3864 "reflect.h2" + if (i + 1 == CPP2_UFCS(ssize)(terms)) { + // Last item + diff += "" + cpp2::to_string(lhs) + "_d = " + cpp2::to_string(cpp2::move(fwd)) + ";"; + diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(cpp2::move(primal)) + ";"; + } + else { + // Temporary + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + // TODO: Get type of expression, in order to define the type of t. + diff += "" + cpp2::to_string(t) + "_d := " + cpp2::to_string(cpp2::move(fwd)) + ";"; + diff += "" + cpp2::to_string(t) + " := " + cpp2::to_string(cpp2::move(primal)) + ";"; - // Temporary test loop - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(multiplicative_terms),1)) - { - std::cout << "debug: found " + cpp2::to_string(CPP2_UFCS(ssize)(multiplicative_terms)) + " is_as_expressions\n"; - for ( auto const& isas : multiplicative_terms ) { - std::cout << "debug: is_as term: \"" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_term)(isas))) + "\"\n"; - if (CPP2_UFCS(is_identifier)(CPP2_UFCS(get_term)(isas))) { - std::cout << "debug: identifier: " + cpp2::to_string(CPP2_UFCS(get_identifier)(CPP2_UFCS(get_term)(isas))) + "\n"; - } + arg_a = cpp2::move(t); } } + } - if (cpp2::impl::cmp_greater(CPP2_UFCS(ssize)(multiplicative_terms),1)) - { - auto arg_a {handle_expression_term(mf, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(multiplicative_terms, 0)))}; - - int i {1}; - for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(multiplicative_terms)); i += 1 ) { - auto arg_b {handle_expression_term(mf, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(multiplicative_terms, i)))}; - - auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(multiplicative_terms, i)))}; - - std::string fwd {""}; - std::string primal {""}; - - if ("*" == op) { - fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a) + "_d"; - primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; - } - else {if ("/" == op) { - fwd = "" + cpp2::to_string(arg_a) + "_d / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; - primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; - } - else { - CPP2_UFCS(error)(mf, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); - }} - -#line 3496 "reflect.h2" - if (i + 1 == CPP2_UFCS(ssize)(multiplicative_terms)) { - // Last item - diff += "" + cpp2::to_string(lhs) + "_d = " + cpp2::to_string(cpp2::move(fwd)) + ";"; - diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(cpp2::move(primal)) + ";"; - } - else { - // Temporary - auto t {gen_temporary()}; - // TODO: Get type of expression, in order to define the type of t. - diff += "" + cpp2::to_string(t) + "_d := " + cpp2::to_string(cpp2::move(fwd)) + ";"; - diff += "" + cpp2::to_string(t) + " := " + cpp2::to_string(cpp2::move(primal)) + ";"; +#line 3881 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ + CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); + } - arg_a = cpp2::move(t); - } - } - } +#line 3889 "reflect.h2" + autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) + : autodiff_handler_base{ ctx_ }{ +#line 3891 "reflect.h2" } -#line 3515 "reflect.h2" - auto autodiff_impl::handle_expression_statement(auto& mf, auto const& expr) & -> void{ +#line 3893 "reflect.h2" + auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { // If this is not an assignment to a parameter or return object, skip it @@ -6459,11 +7094,14 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each // @ is one of a list of operators at the same grammar precedence - handle_expression_terms(mf, CPP2_UFCS(to_string)(cpp2::move(lhs)), CPP2_UFCS(get_terms)(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1)))); + autodiff_expression_handler h {ctx, CPP2_UFCS(to_string)(cpp2::move(lhs))}; + CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); + + append(cpp2::move(h)); } } -#line 3542 "reflect.h2" +#line 3923 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -6487,8 +7125,8 @@ auto autodiff(meta::type_declaration& t) -> void // b) Returns for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 1, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 1, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; } diff += ") = {"; @@ -6500,9 +7138,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } - autodiff_impl ad_impl {}; + autodiff_context ad_ctx {}; + autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 3581 "reflect.h2" +#line 3963 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -6609,7 +7248,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 3597 "reflect.h2" +#line 3979 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -6974,7 +7613,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 3962 "reflect.h2" +#line 4344 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -6990,11 +7629,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 3978 "reflect.h2" +#line 4360 "reflect.h2" // Possible modifiers for a regular expression. // -#line 3982 "reflect.h2" +#line 4364 "reflect.h2" // mod: i // mod: m // mod: s @@ -7002,116 +7641,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 3991 "reflect.h2" +#line 4373 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4000 "reflect.h2" +#line 4382 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4002 "reflect.h2" +#line 4384 "reflect.h2" } -#line 4004 "reflect.h2" +#line 4386 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4006 "reflect.h2" +#line 4388 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4012 "reflect.h2" +#line 4394 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4013 "reflect.h2" +#line 4395 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4014 "reflect.h2" +#line 4396 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4029 "reflect.h2" +#line 4411 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4032 "reflect.h2" +#line 4414 "reflect.h2" } -#line 4034 "reflect.h2" +#line 4416 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4038 "reflect.h2" +#line 4420 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4050 "reflect.h2" +#line 4432 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4053 "reflect.h2" +#line 4435 "reflect.h2" } -#line 4055 "reflect.h2" +#line 4437 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4059 "reflect.h2" +#line 4441 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4069 "reflect.h2" +#line 4451 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4071 "reflect.h2" +#line 4453 "reflect.h2" } -#line 4073 "reflect.h2" +#line 4455 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4077 "reflect.h2" +#line 4459 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4089 "reflect.h2" +#line 4471 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4092 "reflect.h2" +#line 4474 "reflect.h2" } -#line 4094 "reflect.h2" +#line 4476 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4100 "reflect.h2" +#line 4482 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4106 "reflect.h2" +#line 4488 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7120,7 +7759,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4114 "reflect.h2" +#line 4496 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7136,7 +7775,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4142 "reflect.h2" +#line 4524 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7144,14 +7783,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4150 "reflect.h2" +#line 4532 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4157 "reflect.h2" +#line 4539 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7163,15 +7802,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4169 "reflect.h2" +#line 4551 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4174 "reflect.h2" +#line 4556 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4178 "reflect.h2" +#line 4560 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7192,7 +7831,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4204 "reflect.h2" +#line 4586 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7201,20 +7840,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4213 "reflect.h2" +#line 4595 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4219 "reflect.h2" +#line 4601 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4226 "reflect.h2" +#line 4608 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -7229,16 +7868,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4256 "reflect.h2" +#line 4638 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4260 "reflect.h2" +#line 4642 "reflect.h2" } -#line 4266 "reflect.h2" +#line 4648 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -7248,7 +7887,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4276 "reflect.h2" +#line 4658 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -7256,17 +7895,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4283 "reflect.h2" +#line 4665 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4287 "reflect.h2" +#line 4669 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4294 "reflect.h2" +#line 4676 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -7276,7 +7915,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4303 "reflect.h2" +#line 4685 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -7284,24 +7923,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4310 "reflect.h2" +#line 4692 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4318 "reflect.h2" +#line 4700 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4322 "reflect.h2" +#line 4704 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4326 "reflect.h2" +#line 4708 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -7313,22 +7952,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4337 "reflect.h2" +#line 4719 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4343 "reflect.h2" +#line 4725 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4347 "reflect.h2" +#line 4729 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4351 "reflect.h2" +#line 4733 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -7336,7 +7975,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4358 "reflect.h2" +#line 4740 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -7348,10 +7987,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4371 "reflect.h2" +#line 4753 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4374 "reflect.h2" +#line 4756 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -7391,7 +8030,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4414 "reflect.h2" +#line 4796 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -7403,14 +8042,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4425 "reflect.h2" +#line 4807 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4426 "reflect.h2" +#line 4808 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4427 "reflect.h2" +#line 4809 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4429 "reflect.h2" +#line 4811 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -7420,10 +8059,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4438 "reflect.h2" +#line 4820 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4440 "reflect.h2" +#line 4822 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -7445,14 +8084,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4461 "reflect.h2" +#line 4843 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4462 "reflect.h2" +#line 4844 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4463 "reflect.h2" +#line 4845 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4465 "reflect.h2" +#line 4847 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -7466,7 +8105,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4478 "reflect.h2" +#line 4860 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -7488,7 +8127,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4499 "reflect.h2" +#line 4881 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -7499,12 +8138,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4509 "reflect.h2" +#line 4891 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 4510 "reflect.h2" +#line 4892 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 4515 "reflect.h2" +#line 4897 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -7559,7 +8198,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4569 "reflect.h2" +#line 4951 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -7599,7 +8238,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4608 "reflect.h2" +#line 4990 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -7615,21 +8254,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4625 "reflect.h2" +#line 5007 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 4626 "reflect.h2" +#line 5008 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 4627 "reflect.h2" +#line 5009 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 4629 "reflect.h2" +#line 5011 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 4644 "reflect.h2" +#line 5026 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -7637,7 +8276,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4651 "reflect.h2" +#line 5033 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -7647,22 +8286,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 4669 "reflect.h2" +#line 5051 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 4674 "reflect.h2" +#line 5056 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 4680 "reflect.h2" +#line 5062 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 4686 "reflect.h2" +#line 5068 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -7671,7 +8310,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 4694 "reflect.h2" +#line 5076 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -7683,7 +8322,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 4705 "reflect.h2" +#line 5087 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -7691,7 +8330,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 4712 "reflect.h2" +#line 5094 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -7712,7 +8351,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 4733 "reflect.h2" +#line 5115 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -7722,7 +8361,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 4743 "reflect.h2" +#line 5125 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -7745,33 +8384,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 4767 "reflect.h2" +#line 5149 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 4773 "reflect.h2" +#line 5155 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 4777 "reflect.h2" +#line 5159 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 4783 "reflect.h2" +#line 5165 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 4791 "reflect.h2" +#line 5173 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -7780,7 +8419,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 4799 "reflect.h2" +#line 5181 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -7789,22 +8428,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 4809 "reflect.h2" +#line 5191 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 4813 "reflect.h2" +#line 5195 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 4817 "reflect.h2" +#line 5199 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 4821 "reflect.h2" +#line 5203 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -7828,18 +8467,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 4846 "reflect.h2" +#line 5228 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 4861 "reflect.h2" +#line 5243 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 4863 "reflect.h2" +#line 5245 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -7850,15 +8489,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 4878 "reflect.h2" +#line 5260 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 4881 "reflect.h2" +#line 5263 "reflect.h2" } -#line 4883 "reflect.h2" +#line 5265 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -7876,7 +8515,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 4900 "reflect.h2" +#line 5282 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -7884,7 +8523,7 @@ generation_function_context::generation_function_context(){} } } -#line 4907 "reflect.h2" +#line 5289 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -7898,7 +8537,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 4920 "reflect.h2" +#line 5302 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -7914,14 +8553,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 4941 "reflect.h2" +#line 5323 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 4943 "reflect.h2" +#line 5325 "reflect.h2" } -#line 4945 "reflect.h2" +#line 5327 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -7930,11 +8569,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 4960 "reflect.h2" +#line 5342 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 4962 "reflect.h2" +#line 5344 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -7942,7 +8581,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 4969 "reflect.h2" +#line 5351 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -7951,37 +8590,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 4977 "reflect.h2" +#line 5359 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 4991 "reflect.h2" +#line 5373 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 4995 "reflect.h2" +#line 5377 "reflect.h2" } -#line 4997 "reflect.h2" +#line 5379 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5001 "reflect.h2" +#line 5383 "reflect.h2" } -#line 5003 "reflect.h2" +#line 5385 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5007 "reflect.h2" +#line 5389 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -7990,14 +8629,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5013 "reflect.h2" +#line 5395 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5018 "reflect.h2" +#line 5400 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8010,7 +8649,7 @@ size_t i{0}; } } -#line 5030 "reflect.h2" +#line 5412 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8032,7 +8671,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5051 "reflect.h2" +#line 5433 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8051,7 +8690,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5069 "reflect.h2" +#line 5451 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8067,14 +8706,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5084 "reflect.h2" +#line 5466 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5090 "reflect.h2" +#line 5472 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8082,19 +8721,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5107 "reflect.h2" +#line 5489 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5108 "reflect.h2" +#line 5490 "reflect.h2" { -#line 5113 "reflect.h2" +#line 5495 "reflect.h2" } -#line 5116 "reflect.h2" +#line 5498 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8220,7 +8859,7 @@ size_t i{0}; ); } -#line 5241 "reflect.h2" +#line 5623 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -8230,13 +8869,13 @@ size_t i{0}; ); } -#line 5250 "reflect.h2" +#line 5632 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5255 "reflect.h2" +#line 5637 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -8247,12 +8886,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5267 "reflect.h2" +#line 5649 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5272 "reflect.h2" +#line 5654 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -8286,7 +8925,7 @@ size_t i{0}; } -#line 5308 "reflect.h2" +#line 5690 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -8295,19 +8934,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5331 "reflect.h2" +#line 5713 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5332 "reflect.h2" +#line 5714 "reflect.h2" { -#line 5337 "reflect.h2" +#line 5719 "reflect.h2" } -#line 5339 "reflect.h2" +#line 5721 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -8409,19 +9048,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5440 "reflect.h2" +#line 5822 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5444 "reflect.h2" +#line 5826 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5468 "reflect.h2" +#line 5850 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -8440,7 +9079,7 @@ size_t i{0}; return r; } -#line 5486 "reflect.h2" +#line 5868 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -8455,7 +9094,7 @@ size_t i{0}; return r; } -#line 5500 "reflect.h2" +#line 5882 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -8615,7 +9254,7 @@ size_t i{0}; } } -#line 5659 "reflect.h2" +#line 6041 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -8624,7 +9263,7 @@ size_t i{0}; return r; } -#line 5667 "reflect.h2" +#line 6049 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -8643,7 +9282,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 5685 "reflect.h2" +#line 6067 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -8675,7 +9314,7 @@ size_t i{0}; } } -#line 5716 "reflect.h2" +#line 6098 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -8686,7 +9325,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 5728 "reflect.h2" +#line 6110 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -8725,7 +9364,7 @@ size_t i{0}; return r; } -#line 5769 "reflect.h2" +#line 6151 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -8743,7 +9382,7 @@ size_t i{0}; }} } -#line 5789 "reflect.h2" +#line 6171 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -8757,16 +9396,16 @@ size_t i{0}; } } -#line 5815 "reflect.h2" +#line 6197 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 5818 "reflect.h2" +#line 6200 "reflect.h2" } -#line 5820 "reflect.h2" +#line 6202 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -8778,7 +9417,7 @@ size_t i{0}; } } -#line 5831 "reflect.h2" +#line 6213 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -8786,14 +9425,14 @@ size_t i{0}; return r; } -#line 5838 "reflect.h2" +#line 6220 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 5846 "reflect.h2" +#line 6228 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -8819,7 +9458,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 5874 "reflect.h2" +#line 6256 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -8845,11 +9484,11 @@ size_t i{0}; return r; } -#line 5911 "reflect.h2" +#line 6293 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 5913 "reflect.h2" +#line 6295 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -8923,7 +9562,7 @@ size_t i{0}; return nullptr; } -#line 5986 "reflect.h2" +#line 6368 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -8936,7 +9575,7 @@ size_t i{0}; }} } -#line 5998 "reflect.h2" +#line 6380 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -8950,7 +9589,7 @@ size_t i{0}; }} } -#line 6011 "reflect.h2" +#line 6393 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -8970,7 +9609,7 @@ size_t i{0}; return r; } -#line 6030 "reflect.h2" +#line 6412 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -8981,7 +9620,7 @@ size_t i{0}; return r; } -#line 6040 "reflect.h2" +#line 6422 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8993,14 +9632,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6051 "reflect.h2" +#line 6433 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6063 "reflect.h2" +#line 6445 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9024,7 +9663,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6087 "reflect.h2" +#line 6469 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9034,7 +9673,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6099 "reflect.h2" +#line 6481 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9050,7 +9689,7 @@ size_t i{0}; } } -#line 6119 "reflect.h2" +#line 6501 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9068,15 +9707,15 @@ size_t i{0}; }} } -#line 6155 "reflect.h2" +#line 6537 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6158 "reflect.h2" +#line 6540 "reflect.h2" } -#line 6160 "reflect.h2" +#line 6542 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9112,7 +9751,7 @@ size_t i{0}; return source; } -#line 6195 "reflect.h2" +#line 6577 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9128,7 +9767,7 @@ size_t i{0}; } } -#line 6211 "reflect.h2" +#line 6593 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9137,7 +9776,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9192,7 +9831,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6280 "reflect.h2" +#line 6662 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -9314,7 +9953,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6402 "reflect.h2" +#line 6784 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 1c687145a..fa2b90577 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -2433,6 +2433,522 @@ sample_print: (s: std::string_view, indent: i32) = << "\n"; } +simple_traverser: type = { + + traverse: (virtual inout this, expr: meta::expression) = + { + // An expression has other shortcuts to query deeper properties, + // but let's just traverse all the nested grammer elements to + // show how that traversal works + + // The expressions use the pre_traverse function to decide which expression + // they are. The correct one calls traverse only once. + + // The expression's basic payload is just an assignment expression + pre_traverse(expr.as_assignment_expression()); + } + + + pre_traverse: (virtual inout this, binexpr: meta::assignment_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual assignment, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::assignment_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::logical_or_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual logical-or, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::logical_or_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + + pre_traverse: (virtual inout this, binexpr: meta::logical_and_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual logical-and, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::logical_and_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::bit_or_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual bit-or, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::bit_or_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::bit_xor_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual bit-xor, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::bit_xor_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + + pre_traverse: (virtual inout this, binexpr: meta::bit_and_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual bit-and, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::bit_and_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + + pre_traverse: (virtual inout this, binexpr: meta::equality_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual equality, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::equality_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::relational_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual relational, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::relational_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::compare_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual compare, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::compare_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::shift_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual shift, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::shift_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, binexpr: meta::additive_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual additive, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::additive_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + + pre_traverse: (virtual inout this, binexpr: meta::multiplicative_expression) = + { + terms := binexpr.get_terms(); + assert(!terms.empty()); + + // If this has only one term, it's not an actual multiplicative, + // it's holding a lower grammar production so go traverse that + if terms.ssize() == 1 { + pre_traverse(terms.front().get_term()); + } + + // Else we're at an actual binary expression with a rhs + else { + traverse(binexpr); + } + } + + traverse: (virtual inout this, binexpr: meta::multiplicative_expression) = + { + terms := binexpr.get_terms(); + + for terms + do (term) + { + traverse(term.get_term()); + } + } + + pre_traverse: (virtual inout this, isas: meta::is_as_expression) = + { + terms := isas.get_terms(); + + // If this has no additional terms, it's not an actual is-as, + // it's holding a lower grammar production so go traverse that + if terms.empty() { + pre_traverse(isas.get_expression()); + } + + // Else we're at an actual is-as expression with a rhs + else { + traverse(isas); + } + } + + traverse: (virtual inout this, isas: meta::is_as_expression) = + { + terms := isas.get_terms(); + + pre_traverse(isas.get_expression()); + + for terms do (term) { + traverse(term.get_expr()); + } + } + + traverse: (virtual inout this, exprs: meta::expression_list) = + { + for exprs.get_expressions() do (expr) { + traverse(expr); + } + } + + pre_traverse: (virtual inout this, prefix: meta::prefix_expression) = + { + ops := prefix.get_ops(); + + // If this has no additional ops, it's not a naked prefix expr, + // it's holding a lower grammar production so go traverse that + if ops.empty() { + pre_traverse(prefix.get_postfix_expression(),); + } + + // Else we're at an actual prefix expression with ops + else { + traverse(prefix); + } + } + + traverse: (virtual inout this, prefix: meta::prefix_expression) = + { + pre_traverse(prefix.get_postfix_expression()); + } + + pre_traverse: (virtual inout this, postfix: meta::postfix_expression) = + { + terms := postfix.get_terms(); + + // If this has no additional terms, it's not a naked postfix expr, + // it's holding a lower grammar production so go traverse that + if terms.empty() { + traverse(postfix.get_primary_expression()); + } + + // Else we're at an actual postfix expression with ops + else { + traverse(postfix); + } + } + + traverse: (virtual inout this, postfix: meta::postfix_expression) = + { + terms := postfix.get_terms(); + + traverse(postfix.get_primary_expression()); + + for terms do (term) { + if term.is_id_expression() { + traverse(term.get_id_expression()); + } + else if term.is_expression_list() { + traverse(term.get_expression_list()); + } + else if term.is_expression() { + traverse(term.get_expression()); + } + } + } + + traverse: (virtual inout this, uid: meta::unqualified_id) = + { + _ = uid; + } + + + traverse: (virtual inout this, qid: meta::qualified_id) = + { + for qid.get_terms() + do (term) + { + traverse(term.get_unqualified()); + } + } + + + traverse: (virtual inout this, tid: meta::type_id) = + { + if tid.is_postfix_expression() { + traverse(tid.as_postfix_expression()); + } + else if tid.is_qualified_id() { + traverse(tid.as_qualified_id()); + } + else if tid.is_unqualified_id() { + traverse(tid.as_unqualified_id()); + } + else { + // Regular type_id + } + } + + + traverse: (virtual inout this, primary: meta::primary_expression) = + { + if primary.is_identifier() { + // Regular identifier + } + else if primary.is_expression_list() { + traverse(primary.as_expression_list()); + } + else if primary.is_literal() { + // Regular literal + } + else if primary.is_declaration() { + // TODO: traverse(primary.as_declaration()); + } + else { + // Regular primary + } + } + + + traverse: (virtual inout this, idexpr: meta::id_expression) = + { + if idexpr.is_identifier() { + // Regular id + } + else if idexpr.is_qualified() { + traverse(idexpr.as_qualified()); + } + else if idexpr.is_unqualified() { + traverse(idexpr.as_unqualified()); + } + else { + // Regular id expr + } + } +} + //----------------------------------------------------------------------- // @@ -3196,320 +3712,182 @@ sample_traverser: (idexpr: meta::id_expression, indent: i32) = // autodiff - stub // -autodiff_impl: type = { - +autodiff_context: type = { private temporary_count : int = 0; - public diff : std::string = ""; - gen_temporary : (inout this) -> std::string = { temporary_count += 1; return "temp_(temporary_count)$"; } +} - handle_expression_term :(inout this, inout _ /*mf*/, term) -> std::string = { - if term.is_identifier() { - return term.to_string(); - } - else { - t := gen_temporary(); - std::cout << "Handle generation for: (term.to_string())$" << std::endl; - //handle_expression_terms(mf, t, term..get_expression_list()); - return t; - } +autodiff_handler_base: type = { + public ctx: *autodiff_context; + + public diff : std::string = ""; + + operator=: (out this, ctx_: *autodiff_context) = { + ctx = ctx_; } - handle_expression_terms :(inout this, inout mf, lhs: std::string, terms) = { - // Handle binary || - logical_or_terms := terms; - if logical_or_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found as a grammatical - // identifier (this won't compile as Cpp1, but it will - // be visible via @print for development/debugging) - diff += "found_logical_or_with_____"; - count := 0; - for logical_or_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + append: (inout this, in_ref o: autodiff_handler_base) = { + diff += o.diff; + } +} - return; - } +autodiff_expression_handler: type = { + this: simple_traverser = (); + this: autodiff_handler_base; - // Handle binary && - if logical_or_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one logical or term here" ); - } - logical_and_terms := logical_or_terms.front().get_term().get_terms(); - if logical_and_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_logical_and_with_____"; - count := 0; - for logical_and_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + base: type == simple_traverser; - return; - } + public lhs: std::string; - // Handle binary | - if logical_and_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one logical and term here" ); - } - bit_or_terms := logical_and_terms.front().get_term().get_terms(); - if bit_or_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_or_with_____"; - count := 0; - for bit_or_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + operator=: (out this, ctx_: *autodiff_context, lhs_: std::string) = { + autodiff_handler_base = (ctx_); + lhs = lhs_; + } - return; + handle_expression_term :(inout this, term) -> std::string = { + if term.is_identifier() { + return term.to_string(); } + else { + std::cout << "Handle generation for: (term.to_string())$" << std::endl; + t := ctx*.gen_temporary(); + ad : autodiff_expression_handler = (ctx, t); + //ad..traverse(term..get_expression_list()); - // Handle binary ^ - if bit_or_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one bit or term here" ); - } - bit_xor_terms := bit_or_terms.front().get_term().get_terms(); - if bit_xor_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_xor_with_____"; - count := 0; - for bit_xor_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + append(ad); - return; + return t; } + } - // Handle binary & - if bit_xor_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one bit xor term here" ); - } - bit_and_terms := bit_xor_terms.front().get_term().get_terms(); - if bit_and_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_bit_and_with_____"; - count := 0; - for bit_and_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + traverse: (override inout this, expr: meta::expression) = { + base::traverse(expr); + } - return; - } + traverse: (override inout this, binexpr: meta::assignment_expression) = { + binexpr.error( "AD: Assign expressions are not yet handled." ); + } - // Handle binary == and != - if bit_and_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one bit and term here" ); - } - equality_terms := bit_and_terms.front().get_term().get_terms(); - if equality_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_equality_with_____"; - count := 0; - for equality_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + traverse: (override inout this, binexpr: meta::logical_or_expression) = { + binexpr.error( "AD: Logical or expressions are not yet handled." ); + } - return; - } + traverse: (override inout this, binexpr: meta::logical_and_expression) = { + binexpr.error( "AD: Logical and expressions are not yet handled." ); + } - // Handle binary < > <= >= - if equality_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one equality term here" ); - } - relational_terms := equality_terms.front().get_term().get_terms(); - if relational_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_relational_with_____"; - count := 0; - for relational_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + traverse: (override inout this, binexpr: meta::bit_or_expression) = { + binexpr.error( "AD: Bit or expressions are not yet handled." ); + } - return; - } + traverse: (override inout this, binexpr: meta::bit_xor_expression) = { + binexpr.error( "AD: Bit xor expressions are not yet handled." ); + } - // Handle binary <=> - if relational_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one relational term here" ); - } - compare_terms := relational_terms.front().get_term().get_terms(); - if compare_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_compare_with_____"; - count := 0; - for compare_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + traverse: (override inout this, binexpr: meta::bit_and_expression) = { + binexpr.error( "AD: Bit and expressions are not yet handled." ); + } - return; - } + traverse: (override inout this, binexpr: meta::equality_expression) = { + binexpr.error( "AD: Equality or expressions are not yet handled." ); + } - // Handle binary << and >> - if compare_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one compare term here" ); - } - shift_terms := compare_terms.front().get_term().get_terms(); - if shift_terms.ssize() > 1 - { - // TODO: Do whatever is appropriate here... - // For now, just list out what we found (visible via @print)... - diff += "found_shift_with_____"; - count := 0; - for shift_terms do (term) { - if count++ > 1 { - diff += term.get_op() + "___"; - } - diff += term.get_term().to_string() + "___"; - } - diff += ";"; + traverse: (override inout this, binexpr: meta::relational_expression) = { + binexpr.error( "AD: Relational expressions are not yet handled." ); + } - return; - } + traverse: (override inout this, binexpr: meta::compare_expression) = { + binexpr.error( "AD: Compare or expressions are not yet handled." ); + } - // Handle binary + and - - if shift_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one shift term here" ); - } - additive_terms := shift_terms.front().get_term().get_terms(); - if additive_terms.ssize() > 1 - { - first := true; - fwd : std::string = "(lhs)$_d = "; - primal: std::string = "(lhs)$ = "; - for additive_terms do (term) { - if !first { - op := term.get_op().to_string(); - fwd += " (op)$ "; - primal += " (op)$ "; - } + traverse: (override inout this, binexpr: meta::shift_expression) = { + binexpr.error( "AD: Shift or expressions are not yet handled." ); + } - var := handle_expression_term(mf, term.get_term()); - fwd += "(var)$_d"; - primal += "(var)$"; + traverse: (override inout this, binexpr: meta::additive_expression) = { + terms := binexpr.get_terms(); - first = false; + first := true; + fwd : std::string = "(lhs)$_d = "; + primal: std::string = "(lhs)$ = "; + for terms do (term) { + if !first { + op := term.get_op().to_string(); + fwd += " (op)$ "; + primal += " (op)$ "; } - fwd += ";"; - primal += ";"; - - diff += fwd + primal; + var := handle_expression_term(term.get_term()); + fwd += "(var)$_d"; + primal += "(var)$"; - return; + first = false; } - // Handle binary * / % - if additive_terms.ssize() != 1 { - mf.error( "ICE: there should be exactly one additive term here" ); - } - multiplicative_terms := additive_terms.front().get_term().get_terms(); + fwd += ";"; + primal += ";"; - // Temporary test loop - if multiplicative_terms.ssize() > 1 - { - std::cout << "debug: found (multiplicative_terms.ssize())$ is_as_expressions\n"; - for multiplicative_terms do (isas) { - std::cout << "debug: is_as term: \"(isas.get_term().to_string())$\"\n"; - if isas.get_term().is_identifier() { - std::cout << "debug: identifier: (isas.get_term().get_identifier())$\n"; - } - } - } + diff += fwd + primal; + } - if multiplicative_terms.ssize() > 1 - { - arg_a := handle_expression_term(mf, multiplicative_terms[0].get_term()); + traverse: (override inout this, binexpr: meta::multiplicative_expression) = { + terms := binexpr.get_terms(); - i : int = 1; - while i < multiplicative_terms.ssize() next i += 1 { - arg_b := handle_expression_term(mf, multiplicative_terms[i].get_term()); + arg_a := handle_expression_term(terms[0].get_term()); - op := multiplicative_terms[i].get_op().to_string(); + i : int = 1; + while i < terms.ssize() next i += 1 { + arg_b := handle_expression_term(terms[i].get_term()); - fwd : std::string = ""; - primal : std::string = ""; + op := terms[i].get_op().to_string(); - if "*" == op { - fwd = "(arg_a)$ * (arg_b)$_d + (arg_b)$ * (arg_a)$_d"; - primal = "(arg_a)$ * (arg_b)$"; - } - else if "/" == op { - fwd = "(arg_a)$_d / (arg_b)$ - (arg_a)$ * (arg_b)$_d / ((arg_b)$ * (arg_b)$)"; - primal = "(arg_a)$ / (arg_b)$"; - } - else { - mf.error( "unkown multiplicative operator '(op)$'"); - } + fwd : std::string = ""; + primal : std::string = ""; + if "*" == op { + fwd = "(arg_a)$ * (arg_b)$_d + (arg_b)$ * (arg_a)$_d"; + primal = "(arg_a)$ * (arg_b)$"; + } + else if "/" == op { + fwd = "(arg_a)$_d / (arg_b)$ - (arg_a)$ * (arg_b)$_d / ((arg_b)$ * (arg_b)$)"; + primal = "(arg_a)$ / (arg_b)$"; + } + else { + binexpr.error( "unkown multiplicative operator '(op)$'"); + } - if i + 1 == multiplicative_terms.ssize() { - // Last item - diff += "(lhs)$_d = (fwd)$;"; - diff += "(lhs)$ = (primal)$;"; - } - else { - // Temporary - t := gen_temporary(); - // TODO: Get type of expression, in order to define the type of t. - diff += "(t)$_d := (fwd)$;"; - diff += "(t)$ := (primal)$;"; - arg_a = t; - } + if i + 1 == terms.ssize() { + // Last item + diff += "(lhs)$_d = (fwd)$;"; + diff += "(lhs)$ = (primal)$;"; + } + else { + // Temporary + t := ctx*.gen_temporary(); + // TODO: Get type of expression, in order to define the type of t. + diff += "(t)$_d := (fwd)$;"; + diff += "(t)$ := (primal)$;"; + + arg_a = t; } } + } + + traverse: (override inout this, isas: meta::is_as_expression) = { + isas.error( "AD: Is as expressions are not yet handled." ); + } +} + +autodiff_stmt_handler: type = { + this: autodiff_handler_base; + operator=: (out this, ctx_: *autodiff_context) = { + autodiff_handler_base = (ctx_); } handle_expression_statement : (inout this, inout mf, expr) = { @@ -3534,7 +3912,10 @@ autodiff_impl: type = { // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each // @ is one of a list of operators at the same grammar precedence - handle_expression_terms(mf, lhs.to_string(), assignment_terms[1].get_term().get_terms()); + h: autodiff_expression_handler = (ctx, lhs.to_string()); + h.pre_traverse(assignment_terms[1].get_term()); + + append(h); } } } @@ -3562,8 +3943,8 @@ autodiff: (inout t: meta::type_declaration) = // b) Returns for mf.get_returns() do (param) { - diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 1, "; - diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$ = 1, "; + diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; + diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$ = 0.0, "; } diff += ") = {"; @@ -3575,7 +3956,8 @@ autodiff: (inout t: meta::type_declaration) = return; } - ad_impl : autodiff_impl = (); + ad_ctx: autodiff_context = (); + ad_impl : autodiff_stmt_handler = (ad_ctx&); for mf.get_compound_body().get_statements() do (stmt) From 97470ba665d880984bd43f9b0bb7125bf389fec4 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Sat, 9 Aug 2025 14:05:37 +0200 Subject: [PATCH 05/54] Handling of expression lists. --- regression-tests/pure2-autodiff.cpp2 | 5 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 34 +- .../test-results/pure2-autodiff.cpp2.output | 26 + source/reflect.h | 893 +++++++++--------- source/reflect.h2 | 39 +- 6 files changed, 546 insertions(+), 452 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 435d88620..a86728a1a 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -40,6 +40,10 @@ ad_test: @autodiff @print type = { mul_div_2: (x: double, y: double) -> (r: double) = { r = x * y / x; } + + mul_add: (x: double, y: double) -> (r: double) = { + r = x * (x + y); + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -63,4 +67,5 @@ main: () = { write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 462df5e61..b8f644577 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -8,3 +8,4 @@ diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index dbaf35c5c..eab33555b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -68,6 +68,11 @@ using mul_div_2_ret = double; #line 40 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; +using mul_add_ret = double; + + +#line 44 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -109,17 +114,21 @@ struct mul_div_2_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret; +struct mul_add_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 43 "pure2-autodiff.cpp2" +#line 47 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -196,6 +205,13 @@ auto main() -> int; r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } +#line 44 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ + cpp2::impl::deferred_init r; +#line 45 "pure2-autodiff.cpp2" + r.construct(x * (x + y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y; @@ -252,13 +268,20 @@ auto temp_1_d {x * y_d + y * x_d}; auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); return { std::move(r), std::move(r_d) }; } +[[nodiscard]] auto ad_test::mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x_d + y_d}; +auto temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -275,6 +298,7 @@ auto main() -> int{ write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_diff(x, x_d, y, y_d)); write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 4c76146c3..1ac306c95 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -92,6 +92,15 @@ ad_test:/* @autodiff @print */ type = return; } + mul_add:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * (x + y); + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -247,6 +256,23 @@ ad_test:/* @autodiff @print */ type = r = temp_1 / x; return; } + + mul_add_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x_d + y_d; + temp_1: _ = x + y; + r_d = x * temp_1_d + temp_1 * x_d; + r = x * temp_1; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 7ab413ec9..813909a6a 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -114,81 +114,81 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 3886 "reflect.h2" +#line 3905 "reflect.h2" class autodiff_stmt_handler; -#line 4362 "reflect.h2" +#line 4381 "reflect.h2" class expression_flags; -#line 4378 "reflect.h2" +#line 4397 "reflect.h2" class regex_token; -#line 4405 "reflect.h2" +#line 4424 "reflect.h2" class regex_token_check; -#line 4426 "reflect.h2" +#line 4445 "reflect.h2" class regex_token_code; -#line 4447 "reflect.h2" +#line 4466 "reflect.h2" class regex_token_empty; -#line 4465 "reflect.h2" +#line 4484 "reflect.h2" class regex_token_list; -#line 4517 "reflect.h2" +#line 4536 "reflect.h2" class parse_context_group_state; -#line 4578 "reflect.h2" +#line 4597 "reflect.h2" class parse_context_branch_reset_state; -#line 4621 "reflect.h2" +#line 4640 "reflect.h2" class parse_context; -#line 5022 "reflect.h2" +#line 5041 "reflect.h2" class generation_function_context; -#line 5040 "reflect.h2" +#line 5059 "reflect.h2" class generation_context; -#line 5239 "reflect.h2" +#line 5258 "reflect.h2" class alternative_token; -#line 5254 "reflect.h2" +#line 5273 "reflect.h2" class alternative_token_gen; -#line 5319 "reflect.h2" +#line 5338 "reflect.h2" class any_token; -#line 5336 "reflect.h2" +#line 5355 "reflect.h2" class atomic_group_token; -#line 5366 "reflect.h2" +#line 5385 "reflect.h2" class char_token; -#line 5481 "reflect.h2" +#line 5500 "reflect.h2" class class_token; -#line 5705 "reflect.h2" +#line 5724 "reflect.h2" class group_ref_token; -#line 5842 "reflect.h2" +#line 5861 "reflect.h2" class group_token; -#line 6189 "reflect.h2" +#line 6208 "reflect.h2" class lookahead_lookbehind_token; -#line 6284 "reflect.h2" +#line 6303 "reflect.h2" class range_token; -#line 6441 "reflect.h2" +#line 6460 "reflect.h2" class special_range_token; -#line 6527 "reflect.h2" +#line 6546 "reflect.h2" template class regex_generator; -#line 6784 "reflect.h2" +#line 6803 "reflect.h2" } } @@ -1566,80 +1566,82 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: using base = simple_traverser; public: std::string lhs; + public: std::string declare_p; + public: std::string declare_d; - public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_); + public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3751 "reflect.h2" +#line 3755 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3767 "reflect.h2" +#line 3786 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 3771 "reflect.h2" +#line 3790 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3775 "reflect.h2" +#line 3794 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3779 "reflect.h2" +#line 3798 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3783 "reflect.h2" +#line 3802 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3787 "reflect.h2" +#line 3806 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3791 "reflect.h2" +#line 3810 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3795 "reflect.h2" +#line 3814 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3799 "reflect.h2" +#line 3818 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3803 "reflect.h2" +#line 3822 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3807 "reflect.h2" +#line 3826 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3811 "reflect.h2" +#line 3830 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3837 "reflect.h2" +#line 3856 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3881 "reflect.h2" +#line 3900 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 3884 "reflect.h2" +#line 3903 "reflect.h2" }; class autodiff_stmt_handler: public autodiff_handler_base { -#line 3889 "reflect.h2" +#line 3908 "reflect.h2" public: autodiff_stmt_handler(autodiff_context* ctx_); -#line 3893 "reflect.h2" +#line 3912 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 3921 "reflect.h2" +#line 3940 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4358 "reflect.h2" +#line 4377 "reflect.h2" using error_func = std::function x)>; -#line 4362 "reflect.h2" +#line 4381 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1674,20 +1676,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4370 "reflect.h2" +#line 4389 "reflect.h2" }; -#line 4378 "reflect.h2" +#line 4397 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4386 "reflect.h2" +#line 4405 "reflect.h2" public: explicit regex_token(); -#line 4391 "reflect.h2" +#line 4410 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1699,103 +1701,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4397 "reflect.h2" +#line 4416 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4403 "reflect.h2" +#line 4422 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4409 "reflect.h2" +#line 4428 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4416 "reflect.h2" +#line 4435 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4420 "reflect.h2" +#line 4439 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4421 "reflect.h2" +#line 4440 "reflect.h2" }; -#line 4424 "reflect.h2" +#line 4443 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4430 "reflect.h2" +#line 4449 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4437 "reflect.h2" +#line 4456 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4441 "reflect.h2" +#line 4460 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4442 "reflect.h2" +#line 4461 "reflect.h2" }; -#line 4445 "reflect.h2" +#line 4464 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4451 "reflect.h2" +#line 4470 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4455 "reflect.h2" +#line 4474 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4459 "reflect.h2" +#line 4478 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4460 "reflect.h2" +#line 4479 "reflect.h2" }; -#line 4463 "reflect.h2" +#line 4482 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4469 "reflect.h2" +#line 4488 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4476 "reflect.h2" +#line 4495 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4482 "reflect.h2" +#line 4501 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4488 "reflect.h2" +#line 4507 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4496 "reflect.h2" +#line 4515 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1803,10 +1805,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4508 "reflect.h2" +#line 4527 "reflect.h2" }; -#line 4511 "reflect.h2" +#line 4530 "reflect.h2" // // Parse and generation context. // @@ -1822,33 +1824,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4531 "reflect.h2" +#line 4550 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4538 "reflect.h2" +#line 4557 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4550 "reflect.h2" +#line 4569 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4555 "reflect.h2" +#line 4574 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4559 "reflect.h2" +#line 4578 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4573 "reflect.h2" +#line 4592 "reflect.h2" }; -#line 4576 "reflect.h2" +#line 4595 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1861,25 +1863,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4594 "reflect.h2" +#line 4613 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4600 "reflect.h2" +#line 4619 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4607 "reflect.h2" +#line 4626 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4614 "reflect.h2" +#line 4633 "reflect.h2" }; -#line 4617 "reflect.h2" +#line 4636 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1895,7 +1897,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4633 "reflect.h2" +#line 4652 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1903,64 +1905,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4644 "reflect.h2" +#line 4663 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4657 "reflect.h2" +#line 4676 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4665 "reflect.h2" +#line 4684 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4669 "reflect.h2" +#line 4688 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4673 "reflect.h2" +#line 4692 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4685 "reflect.h2" +#line 4704 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4692 "reflect.h2" +#line 4711 "reflect.h2" public: auto next_alternative() & -> void; -#line 4698 "reflect.h2" +#line 4717 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4704 "reflect.h2" +#line 4723 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4708 "reflect.h2" +#line 4727 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4719 "reflect.h2" +#line 4738 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4723 "reflect.h2" +#line 4742 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4729 "reflect.h2" +#line 4748 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4733 "reflect.h2" +#line 4752 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4740 "reflect.h2" +#line 4759 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4751 "reflect.h2" +#line 4770 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1968,51 +1970,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4795 "reflect.h2" +#line 4814 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4807 "reflect.h2" +#line 4826 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4820 "reflect.h2" +#line 4839 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4843 "reflect.h2" +#line 4862 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4860 "reflect.h2" +#line 4879 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4881 "reflect.h2" +#line 4900 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 4891 "reflect.h2" +#line 4910 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 4895 "reflect.h2" +#line 4914 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 4951 "reflect.h2" +#line 4970 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 4990 "reflect.h2" +#line 5009 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5005 "reflect.h2" +#line 5024 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2024,10 +2026,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5016 "reflect.h2" +#line 5035 "reflect.h2" }; -#line 5019 "reflect.h2" +#line 5038 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2037,16 +2039,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5033 "reflect.h2" +#line 5052 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5036 "reflect.h2" +#line 5055 "reflect.h2" }; -#line 5039 "reflect.h2" +#line 5058 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2066,68 +2068,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5061 "reflect.h2" +#line 5080 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5067 "reflect.h2" +#line 5086 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5076 "reflect.h2" +#line 5095 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5087 "reflect.h2" +#line 5106 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5094 "reflect.h2" +#line 5113 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5114 "reflect.h2" +#line 5133 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5124 "reflect.h2" +#line 5143 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5147 "reflect.h2" +#line 5166 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5155 "reflect.h2" +#line 5174 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5159 "reflect.h2" +#line 5178 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5165 "reflect.h2" +#line 5184 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5171 "reflect.h2" +#line 5190 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5181 "reflect.h2" +#line 5200 "reflect.h2" public: auto finish_context() & -> void; -#line 5189 "reflect.h2" +#line 5208 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5195 "reflect.h2" +#line 5214 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5199 "reflect.h2" +#line 5218 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5203 "reflect.h2" +#line 5222 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5227 "reflect.h2" +#line 5246 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2135,7 +2137,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5233 "reflect.h2" +#line 5252 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2155,27 +2157,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5252 "reflect.h2" +#line 5271 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5258 "reflect.h2" +#line 5277 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5265 "reflect.h2" +#line 5284 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5282 "reflect.h2" +#line 5301 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5289 "reflect.h2" +#line 5308 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5302 "reflect.h2" +#line 5321 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2183,19 +2185,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5314 "reflect.h2" +#line 5333 "reflect.h2" }; -#line 5317 "reflect.h2" +#line 5336 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5323 "reflect.h2" +#line 5342 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5327 "reflect.h2" +#line 5346 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2203,7 +2205,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5332 "reflect.h2" +#line 5351 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2211,17 +2213,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5340 "reflect.h2" +#line 5359 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5351 "reflect.h2" +#line 5370 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5359 "reflect.h2" +#line 5378 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2229,7 +2231,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5362 "reflect.h2" +#line 5381 "reflect.h2" }; // Regex syntax: a @@ -2237,34 +2239,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5370 "reflect.h2" +#line 5389 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5379 "reflect.h2" +#line 5398 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5385 "reflect.h2" +#line 5404 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5389 "reflect.h2" +#line 5408 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5412 "reflect.h2" +#line 5431 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5433 "reflect.h2" +#line 5452 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5451 "reflect.h2" +#line 5470 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5466 "reflect.h2" +#line 5485 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5472 "reflect.h2" +#line 5491 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2272,33 +2274,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5476 "reflect.h2" +#line 5495 "reflect.h2" }; -#line 5479 "reflect.h2" +#line 5498 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5485 "reflect.h2" +#line 5504 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5497 "reflect.h2" +#line 5516 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5623 "reflect.h2" +#line 5642 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5632 "reflect.h2" +#line 5651 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5637 "reflect.h2" +#line 5656 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2306,20 +2308,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5644 "reflect.h2" +#line 5663 "reflect.h2" }; -#line 5647 "reflect.h2" +#line 5666 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5688 "reflect.h2" +#line 5707 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5699 "reflect.h2" +#line 5718 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2329,20 +2331,20 @@ class class_token class group_ref_token : public regex_token { -#line 5709 "reflect.h2" +#line 5728 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5721 "reflect.h2" +#line 5740 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5822 "reflect.h2" +#line 5841 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5826 "reflect.h2" +#line 5845 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2350,10 +2352,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5829 "reflect.h2" +#line 5848 "reflect.h2" }; -#line 5832 "reflect.h2" +#line 5851 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2367,29 +2369,29 @@ class group_ref_token class group_token : public regex_token { -#line 5846 "reflect.h2" +#line 5865 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5868 "reflect.h2" +#line 5887 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5882 "reflect.h2" +#line 5901 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6041 "reflect.h2" +#line 6060 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6049 "reflect.h2" +#line 6068 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6067 "reflect.h2" +#line 6086 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6098 "reflect.h2" +#line 6117 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2398,25 +2400,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6105 "reflect.h2" +#line 6124 "reflect.h2" }; -#line 6108 "reflect.h2" +#line 6127 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6149 "reflect.h2" +#line 6168 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6169 "reflect.h2" +#line 6188 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6185 "reflect.h2" +#line 6204 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2424,20 +2426,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6193 "reflect.h2" +#line 6212 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6202 "reflect.h2" +#line 6221 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6213 "reflect.h2" +#line 6232 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6220 "reflect.h2" +#line 6239 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2445,26 +2447,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6223 "reflect.h2" +#line 6242 "reflect.h2" }; -#line 6226 "reflect.h2" +#line 6245 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6254 "reflect.h2" +#line 6273 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6282 "reflect.h2" +#line 6301 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6288 "reflect.h2" +#line 6307 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2474,22 +2476,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6368 "reflect.h2" +#line 6387 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6380 "reflect.h2" +#line 6399 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6393 "reflect.h2" +#line 6412 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6412 "reflect.h2" +#line 6431 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6422 "reflect.h2" +#line 6441 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6433 "reflect.h2" +#line 6452 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2497,16 +2499,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6436 "reflect.h2" +#line 6455 "reflect.h2" }; -#line 6439 "reflect.h2" +#line 6458 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6445 "reflect.h2" +#line 6464 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2515,7 +2517,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6475 "reflect.h2" +#line 6494 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2524,14 +2526,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6497 "reflect.h2" +#line 6516 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6519 "reflect.h2" +#line 6538 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2552,24 +2554,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6542 "reflect.h2" +#line 6561 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6577 "reflect.h2" +#line 6596 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6591 "reflect.h2" +#line 6610 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6603 "reflect.h2" +#line 6622 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6658 "reflect.h2" +#line 6677 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2580,7 +2582,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6784 "reflect.h2" +#line 6803 "reflect.h2" } } @@ -6906,94 +6908,111 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += o.diff; } -#line 3746 "reflect.h2" - autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_) +#line 3748 "reflect.h2" + autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } - , lhs{ lhs_ }{ + , lhs{ lhs_ } + , declare_p{ declare_ } + , declare_d{ declare_ }{ -#line 3749 "reflect.h2" +#line 3753 "reflect.h2" } -#line 3751 "reflect.h2" +#line 3755 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); } - else { - std::cout << "Handle generation for: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + "" << std::endl; - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - autodiff_expression_handler ad {ctx, t}; - //ad..traverse(term..get_expression_list()); + else {if (CPP2_UFCS(is_expression_list)(term)) { + auto exprs {term.as_expression_list().get_expressions()}; + if (CPP2_UFCS(ssize)(exprs) != 1) { + CPP2_UFCS(error)(term, "Can not handle multiple expressions. (term.to_string())"); + return "error"; + } + auto expr {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(exprs), 0)}; + auto bin_expr {expr.as_assignment_expression()}; + + if (CPP2_UFCS(terms_size)(bin_expr) != 0) { + CPP2_UFCS(error)(term, "Can not handle assign expr inside of expression. " + cpp2::to_string(CPP2_UFCS(to_string)(cpp2::move(expr))) + ""); + return "error"; + } + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + autodiff_expression_handler ad {ctx, t, ":"}; // TODO: get type of expression + ad.pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(CPP2_UFCS(get_terms)(cpp2::move(bin_expr))))); append(cpp2::move(ad)); return t; } + else { + CPP2_UFCS(error)(term, "Do not know how to handle AD for: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + ""); + return "error"; + }} } -#line 3767 "reflect.h2" +#line 3786 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 3771 "reflect.h2" +#line 3790 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 3775 "reflect.h2" +#line 3794 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 3779 "reflect.h2" +#line 3798 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 3783 "reflect.h2" +#line 3802 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 3787 "reflect.h2" +#line 3806 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 3791 "reflect.h2" +#line 3810 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 3795 "reflect.h2" +#line 3814 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 3799 "reflect.h2" +#line 3818 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 3803 "reflect.h2" +#line 3822 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 3807 "reflect.h2" +#line 3826 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 3811 "reflect.h2" +#line 3830 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto first {true}; - std::string fwd {"" + cpp2::to_string(lhs) + "_d = "}; - std::string primal {"" + cpp2::to_string(lhs) + " = "}; + std::string fwd {"" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= "}; + std::string primal {"" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= "}; for ( auto const& term : cpp2::move(terms) ) { if (!(first)) { auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term))}; @@ -7014,7 +7033,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 3837 "reflect.h2" +#line 3856 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7041,11 +7060,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 3864 "reflect.h2" +#line 3883 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item - diff += "" + cpp2::to_string(lhs) + "_d = " + cpp2::to_string(cpp2::move(fwd)) + ";"; - diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(cpp2::move(primal)) + ";"; + diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; + diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(cpp2::move(primal)) + ";"; } else { // Temporary @@ -7059,19 +7078,19 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3881 "reflect.h2" +#line 3900 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 3889 "reflect.h2" +#line 3908 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) : autodiff_handler_base{ ctx_ }{ -#line 3891 "reflect.h2" +#line 3910 "reflect.h2" } -#line 3893 "reflect.h2" +#line 3912 "reflect.h2" auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7101,7 +7120,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3923 "reflect.h2" +#line 3942 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7141,7 +7160,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 3963 "reflect.h2" +#line 3982 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -7248,7 +7267,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 3979 "reflect.h2" +#line 3998 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -7613,7 +7632,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4344 "reflect.h2" +#line 4363 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -7629,11 +7648,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4360 "reflect.h2" +#line 4379 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4364 "reflect.h2" +#line 4383 "reflect.h2" // mod: i // mod: m // mod: s @@ -7641,116 +7660,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4373 "reflect.h2" +#line 4392 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4382 "reflect.h2" +#line 4401 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4384 "reflect.h2" +#line 4403 "reflect.h2" } -#line 4386 "reflect.h2" +#line 4405 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4388 "reflect.h2" +#line 4407 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4394 "reflect.h2" +#line 4413 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4395 "reflect.h2" +#line 4414 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4396 "reflect.h2" +#line 4415 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4411 "reflect.h2" +#line 4430 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4414 "reflect.h2" +#line 4433 "reflect.h2" } -#line 4416 "reflect.h2" +#line 4435 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4420 "reflect.h2" +#line 4439 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4432 "reflect.h2" +#line 4451 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4435 "reflect.h2" +#line 4454 "reflect.h2" } -#line 4437 "reflect.h2" +#line 4456 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4441 "reflect.h2" +#line 4460 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4451 "reflect.h2" +#line 4470 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4453 "reflect.h2" +#line 4472 "reflect.h2" } -#line 4455 "reflect.h2" +#line 4474 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4459 "reflect.h2" +#line 4478 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4471 "reflect.h2" +#line 4490 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4474 "reflect.h2" +#line 4493 "reflect.h2" } -#line 4476 "reflect.h2" +#line 4495 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4482 "reflect.h2" +#line 4501 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4488 "reflect.h2" +#line 4507 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7759,7 +7778,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4496 "reflect.h2" +#line 4515 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7775,7 +7794,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4524 "reflect.h2" +#line 4543 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7783,14 +7802,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4532 "reflect.h2" +#line 4551 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4539 "reflect.h2" +#line 4558 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7802,15 +7821,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4551 "reflect.h2" +#line 4570 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4556 "reflect.h2" +#line 4575 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4560 "reflect.h2" +#line 4579 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7831,7 +7850,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4586 "reflect.h2" +#line 4605 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7840,20 +7859,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4595 "reflect.h2" +#line 4614 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4601 "reflect.h2" +#line 4620 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4608 "reflect.h2" +#line 4627 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -7868,16 +7887,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4638 "reflect.h2" +#line 4657 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4642 "reflect.h2" +#line 4661 "reflect.h2" } -#line 4648 "reflect.h2" +#line 4667 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -7887,7 +7906,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4658 "reflect.h2" +#line 4677 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -7895,17 +7914,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4665 "reflect.h2" +#line 4684 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4669 "reflect.h2" +#line 4688 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4676 "reflect.h2" +#line 4695 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -7915,7 +7934,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4685 "reflect.h2" +#line 4704 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -7923,24 +7942,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4692 "reflect.h2" +#line 4711 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4700 "reflect.h2" +#line 4719 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4704 "reflect.h2" +#line 4723 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4708 "reflect.h2" +#line 4727 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -7952,22 +7971,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4719 "reflect.h2" +#line 4738 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4725 "reflect.h2" +#line 4744 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4729 "reflect.h2" +#line 4748 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4733 "reflect.h2" +#line 4752 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -7975,7 +7994,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4740 "reflect.h2" +#line 4759 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -7987,10 +8006,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4753 "reflect.h2" +#line 4772 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4756 "reflect.h2" +#line 4775 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8030,7 +8049,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4796 "reflect.h2" +#line 4815 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8042,14 +8061,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4807 "reflect.h2" +#line 4826 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4808 "reflect.h2" +#line 4827 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4809 "reflect.h2" +#line 4828 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4811 "reflect.h2" +#line 4830 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8059,10 +8078,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4820 "reflect.h2" +#line 4839 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4822 "reflect.h2" +#line 4841 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8084,14 +8103,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4843 "reflect.h2" +#line 4862 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4844 "reflect.h2" +#line 4863 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4845 "reflect.h2" +#line 4864 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4847 "reflect.h2" +#line 4866 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8105,7 +8124,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4860 "reflect.h2" +#line 4879 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8127,7 +8146,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4881 "reflect.h2" +#line 4900 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8138,12 +8157,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4891 "reflect.h2" +#line 4910 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 4892 "reflect.h2" +#line 4911 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 4897 "reflect.h2" +#line 4916 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8198,7 +8217,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4951 "reflect.h2" +#line 4970 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8238,7 +8257,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4990 "reflect.h2" +#line 5009 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8254,21 +8273,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5007 "reflect.h2" +#line 5026 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5008 "reflect.h2" +#line 5027 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5009 "reflect.h2" +#line 5028 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5011 "reflect.h2" +#line 5030 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5026 "reflect.h2" +#line 5045 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8276,7 +8295,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5033 "reflect.h2" +#line 5052 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8286,22 +8305,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5051 "reflect.h2" +#line 5070 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5056 "reflect.h2" +#line 5075 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5062 "reflect.h2" +#line 5081 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5068 "reflect.h2" +#line 5087 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8310,7 +8329,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5076 "reflect.h2" +#line 5095 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8322,7 +8341,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5087 "reflect.h2" +#line 5106 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8330,7 +8349,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5094 "reflect.h2" +#line 5113 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8351,7 +8370,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5115 "reflect.h2" +#line 5134 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8361,7 +8380,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5125 "reflect.h2" +#line 5144 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8384,33 +8403,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5149 "reflect.h2" +#line 5168 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5155 "reflect.h2" +#line 5174 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5159 "reflect.h2" +#line 5178 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5165 "reflect.h2" +#line 5184 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5173 "reflect.h2" +#line 5192 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8419,7 +8438,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5181 "reflect.h2" +#line 5200 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8428,22 +8447,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5191 "reflect.h2" +#line 5210 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5195 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5199 "reflect.h2" +#line 5218 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5203 "reflect.h2" +#line 5222 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8467,18 +8486,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5228 "reflect.h2" +#line 5247 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5243 "reflect.h2" +#line 5262 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5245 "reflect.h2" +#line 5264 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8489,15 +8508,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5260 "reflect.h2" +#line 5279 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5263 "reflect.h2" +#line 5282 "reflect.h2" } -#line 5265 "reflect.h2" +#line 5284 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8515,7 +8534,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5282 "reflect.h2" +#line 5301 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8523,7 +8542,7 @@ generation_function_context::generation_function_context(){} } } -#line 5289 "reflect.h2" +#line 5308 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8537,7 +8556,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5302 "reflect.h2" +#line 5321 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8553,14 +8572,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5323 "reflect.h2" +#line 5342 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5325 "reflect.h2" +#line 5344 "reflect.h2" } -#line 5327 "reflect.h2" +#line 5346 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8569,11 +8588,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5342 "reflect.h2" +#line 5361 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5344 "reflect.h2" +#line 5363 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8581,7 +8600,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5351 "reflect.h2" +#line 5370 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8590,37 +8609,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5359 "reflect.h2" +#line 5378 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5373 "reflect.h2" +#line 5392 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5377 "reflect.h2" +#line 5396 "reflect.h2" } -#line 5379 "reflect.h2" +#line 5398 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5383 "reflect.h2" +#line 5402 "reflect.h2" } -#line 5385 "reflect.h2" +#line 5404 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5389 "reflect.h2" +#line 5408 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -8629,14 +8648,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5395 "reflect.h2" +#line 5414 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5400 "reflect.h2" +#line 5419 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8649,7 +8668,7 @@ size_t i{0}; } } -#line 5412 "reflect.h2" +#line 5431 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8671,7 +8690,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5433 "reflect.h2" +#line 5452 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8690,7 +8709,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5451 "reflect.h2" +#line 5470 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8706,14 +8725,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5466 "reflect.h2" +#line 5485 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5472 "reflect.h2" +#line 5491 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8721,19 +8740,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5489 "reflect.h2" +#line 5508 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5490 "reflect.h2" +#line 5509 "reflect.h2" { -#line 5495 "reflect.h2" +#line 5514 "reflect.h2" } -#line 5498 "reflect.h2" +#line 5517 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8859,7 +8878,7 @@ size_t i{0}; ); } -#line 5623 "reflect.h2" +#line 5642 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -8869,13 +8888,13 @@ size_t i{0}; ); } -#line 5632 "reflect.h2" +#line 5651 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5637 "reflect.h2" +#line 5656 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -8886,12 +8905,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5649 "reflect.h2" +#line 5668 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5654 "reflect.h2" +#line 5673 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -8925,7 +8944,7 @@ size_t i{0}; } -#line 5690 "reflect.h2" +#line 5709 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -8934,19 +8953,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5713 "reflect.h2" +#line 5732 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5714 "reflect.h2" +#line 5733 "reflect.h2" { -#line 5719 "reflect.h2" +#line 5738 "reflect.h2" } -#line 5721 "reflect.h2" +#line 5740 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9048,19 +9067,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5822 "reflect.h2" +#line 5841 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5826 "reflect.h2" +#line 5845 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5850 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9079,7 +9098,7 @@ size_t i{0}; return r; } -#line 5868 "reflect.h2" +#line 5887 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9094,7 +9113,7 @@ size_t i{0}; return r; } -#line 5882 "reflect.h2" +#line 5901 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9254,7 +9273,7 @@ size_t i{0}; } } -#line 6041 "reflect.h2" +#line 6060 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9263,7 +9282,7 @@ size_t i{0}; return r; } -#line 6049 "reflect.h2" +#line 6068 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9282,7 +9301,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6067 "reflect.h2" +#line 6086 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9314,7 +9333,7 @@ size_t i{0}; } } -#line 6098 "reflect.h2" +#line 6117 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9325,7 +9344,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6110 "reflect.h2" +#line 6129 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9364,7 +9383,7 @@ size_t i{0}; return r; } -#line 6151 "reflect.h2" +#line 6170 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9382,7 +9401,7 @@ size_t i{0}; }} } -#line 6171 "reflect.h2" +#line 6190 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9396,16 +9415,16 @@ size_t i{0}; } } -#line 6197 "reflect.h2" +#line 6216 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6200 "reflect.h2" +#line 6219 "reflect.h2" } -#line 6202 "reflect.h2" +#line 6221 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9417,7 +9436,7 @@ size_t i{0}; } } -#line 6213 "reflect.h2" +#line 6232 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9425,14 +9444,14 @@ size_t i{0}; return r; } -#line 6220 "reflect.h2" +#line 6239 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6228 "reflect.h2" +#line 6247 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9458,7 +9477,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6256 "reflect.h2" +#line 6275 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9484,11 +9503,11 @@ size_t i{0}; return r; } -#line 6293 "reflect.h2" +#line 6312 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6295 "reflect.h2" +#line 6314 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9562,7 +9581,7 @@ size_t i{0}; return nullptr; } -#line 6368 "reflect.h2" +#line 6387 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9575,7 +9594,7 @@ size_t i{0}; }} } -#line 6380 "reflect.h2" +#line 6399 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9589,7 +9608,7 @@ size_t i{0}; }} } -#line 6393 "reflect.h2" +#line 6412 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9609,7 +9628,7 @@ size_t i{0}; return r; } -#line 6412 "reflect.h2" +#line 6431 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -9620,7 +9639,7 @@ size_t i{0}; return r; } -#line 6422 "reflect.h2" +#line 6441 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9632,14 +9651,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6433 "reflect.h2" +#line 6452 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6445 "reflect.h2" +#line 6464 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9663,7 +9682,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6469 "reflect.h2" +#line 6488 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9673,7 +9692,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6481 "reflect.h2" +#line 6500 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9689,7 +9708,7 @@ size_t i{0}; } } -#line 6501 "reflect.h2" +#line 6520 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9707,15 +9726,15 @@ size_t i{0}; }} } -#line 6537 "reflect.h2" +#line 6556 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6540 "reflect.h2" +#line 6559 "reflect.h2" } -#line 6542 "reflect.h2" +#line 6561 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9751,7 +9770,7 @@ size_t i{0}; return source; } -#line 6577 "reflect.h2" +#line 6596 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9767,7 +9786,7 @@ size_t i{0}; } } -#line 6593 "reflect.h2" +#line 6612 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9776,7 +9795,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9831,7 +9850,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6662 "reflect.h2" +#line 6681 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -9953,7 +9972,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6784 "reflect.h2" +#line 6803 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index fa2b90577..f9ca5a68d 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3742,26 +3742,45 @@ autodiff_expression_handler: type = { base: type == simple_traverser; public lhs: std::string; + public declare_p: std::string; + public declare_d: std::string; - operator=: (out this, ctx_: *autodiff_context, lhs_: std::string) = { + operator=: (out this, ctx_: *autodiff_context, lhs_: std::string, declare_: std::string = "") = { autodiff_handler_base = (ctx_); lhs = lhs_; + declare_p = declare_; + declare_d = declare_; } handle_expression_term :(inout this, term) -> std::string = { if term.is_identifier() { return term.to_string(); } - else { - std::cout << "Handle generation for: (term.to_string())$" << std::endl; - t := ctx*.gen_temporary(); - ad : autodiff_expression_handler = (ctx, t); - //ad..traverse(term..get_expression_list()); + else if term.is_expression_list() { + exprs := term..as_expression_list()..get_expressions(); + if exprs.ssize() != 1 { + term.error("Can not handle multiple expressions. (term.to_string())"); + return "error"; + } + expr := exprs[0]; + bin_expr := expr..as_assignment_expression(); + + if bin_expr.terms_size() != 0 { + term.error("Can not handle assign expr inside of expression. (expr.to_string())$"); + return "error"; + } + t := ctx*.gen_temporary(); + ad : autodiff_expression_handler = (ctx, t, ":"); // TODO: get type of expression + ad..pre_traverse(bin_expr.get_terms().front().get_term()); append(ad); return t; } + else { + term.error( "Do not know how to handle AD for: (term.to_string())$"); + return "error"; + } } traverse: (override inout this, expr: meta::expression) = { @@ -3812,8 +3831,8 @@ autodiff_expression_handler: type = { terms := binexpr.get_terms(); first := true; - fwd : std::string = "(lhs)$_d = "; - primal: std::string = "(lhs)$ = "; + fwd : std::string = "(lhs)$_d (declare_p)$= "; + primal: std::string = "(lhs)$ (declare_d)$= "; for terms do (term) { if !first { op := term.get_op().to_string(); @@ -3863,8 +3882,8 @@ autodiff_expression_handler: type = { if i + 1 == terms.ssize() { // Last item - diff += "(lhs)$_d = (fwd)$;"; - diff += "(lhs)$ = (primal)$;"; + diff += "(lhs)$_d (declare_p)$= (fwd)$;"; + diff += "(lhs)$ (declare_d)$= (primal)$;"; } else { // Temporary From 965af062bb193e73bd90046d0234642ba20c34fc Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Sat, 9 Aug 2025 14:40:50 +0200 Subject: [PATCH 06/54] Handling of expresson terms. --- regression-tests/pure2-autodiff.cpp2 | 5 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 34 +- .../test-results/pure2-autodiff.cpp2.output | 26 + source/reflect.h | 853 +++++++++--------- source/reflect.h2 | 11 +- 6 files changed, 500 insertions(+), 430 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index a86728a1a..c3e6d1f85 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -44,6 +44,10 @@ ad_test: @autodiff @print type = { mul_add: (x: double, y: double) -> (r: double) = { r = x * (x + y); } + + add_mul: (x: double, y: double) -> (r: double) = { + r = x + x * y; + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -68,4 +72,5 @@ main: () = { write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index b8f644577..bc1838275 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -9,3 +9,4 @@ diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index eab33555b..466b26d0b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -73,6 +73,11 @@ using mul_add_ret = double; #line 44 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; +using add_mul_ret = double; + + +#line 48 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -118,17 +123,21 @@ struct mul_add_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret; +struct add_mul_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 47 "pure2-autodiff.cpp2" +#line 51 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -212,6 +221,13 @@ auto main() -> int; r.construct(x * (x + y)); return std::move(r.value()); } +#line 48 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ + cpp2::impl::deferred_init r; +#line 49 "pure2-autodiff.cpp2" + r.construct(x + x * y); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y; @@ -275,13 +291,20 @@ auto temp_1_d {x_d + y_d}; auto temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; } +[[nodiscard]] auto ad_test::add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x * y_d + y * x_d}; +auto temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d);r = x + cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -299,6 +322,7 @@ auto main() -> int{ write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 1ac306c95..29d6eaa6f 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -101,6 +101,15 @@ ad_test:/* @autodiff @print */ type = return; } + add_mul:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + x * y; + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -273,6 +282,23 @@ ad_test:/* @autodiff @print */ type = r = x * temp_1; return; } + + add_mul_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x * y_d + y * x_d; + temp_1: _ = x * y; + r_d = x_d + temp_1_d; + r = x + temp_1; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 813909a6a..865a83a75 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -114,81 +114,81 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 3905 "reflect.h2" +#line 3912 "reflect.h2" class autodiff_stmt_handler; -#line 4381 "reflect.h2" +#line 4388 "reflect.h2" class expression_flags; -#line 4397 "reflect.h2" +#line 4404 "reflect.h2" class regex_token; -#line 4424 "reflect.h2" +#line 4431 "reflect.h2" class regex_token_check; -#line 4445 "reflect.h2" +#line 4452 "reflect.h2" class regex_token_code; -#line 4466 "reflect.h2" +#line 4473 "reflect.h2" class regex_token_empty; -#line 4484 "reflect.h2" +#line 4491 "reflect.h2" class regex_token_list; -#line 4536 "reflect.h2" +#line 4543 "reflect.h2" class parse_context_group_state; -#line 4597 "reflect.h2" +#line 4604 "reflect.h2" class parse_context_branch_reset_state; -#line 4640 "reflect.h2" +#line 4647 "reflect.h2" class parse_context; -#line 5041 "reflect.h2" +#line 5048 "reflect.h2" class generation_function_context; -#line 5059 "reflect.h2" +#line 5066 "reflect.h2" class generation_context; -#line 5258 "reflect.h2" +#line 5265 "reflect.h2" class alternative_token; -#line 5273 "reflect.h2" +#line 5280 "reflect.h2" class alternative_token_gen; -#line 5338 "reflect.h2" +#line 5345 "reflect.h2" class any_token; -#line 5355 "reflect.h2" +#line 5362 "reflect.h2" class atomic_group_token; -#line 5385 "reflect.h2" +#line 5392 "reflect.h2" class char_token; -#line 5500 "reflect.h2" +#line 5507 "reflect.h2" class class_token; -#line 5724 "reflect.h2" +#line 5731 "reflect.h2" class group_ref_token; -#line 5861 "reflect.h2" +#line 5868 "reflect.h2" class group_token; -#line 6208 "reflect.h2" +#line 6215 "reflect.h2" class lookahead_lookbehind_token; -#line 6303 "reflect.h2" +#line 6310 "reflect.h2" class range_token; -#line 6460 "reflect.h2" +#line 6467 "reflect.h2" class special_range_token; -#line 6546 "reflect.h2" +#line 6553 "reflect.h2" template class regex_generator; -#line 6803 "reflect.h2" +#line 6810 "reflect.h2" } } @@ -1574,74 +1574,74 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand #line 3755 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3786 "reflect.h2" +#line 3793 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 3790 "reflect.h2" +#line 3797 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3794 "reflect.h2" +#line 3801 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3798 "reflect.h2" +#line 3805 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3802 "reflect.h2" +#line 3809 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3806 "reflect.h2" +#line 3813 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3810 "reflect.h2" +#line 3817 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3814 "reflect.h2" +#line 3821 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3818 "reflect.h2" +#line 3825 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3822 "reflect.h2" +#line 3829 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3826 "reflect.h2" +#line 3833 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3830 "reflect.h2" +#line 3837 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3856 "reflect.h2" +#line 3863 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3900 "reflect.h2" +#line 3907 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 3903 "reflect.h2" +#line 3910 "reflect.h2" }; class autodiff_stmt_handler: public autodiff_handler_base { -#line 3908 "reflect.h2" +#line 3915 "reflect.h2" public: autodiff_stmt_handler(autodiff_context* ctx_); -#line 3912 "reflect.h2" +#line 3919 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 3940 "reflect.h2" +#line 3947 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4377 "reflect.h2" +#line 4384 "reflect.h2" using error_func = std::function x)>; -#line 4381 "reflect.h2" +#line 4388 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1676,20 +1676,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4389 "reflect.h2" +#line 4396 "reflect.h2" }; -#line 4397 "reflect.h2" +#line 4404 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4405 "reflect.h2" +#line 4412 "reflect.h2" public: explicit regex_token(); -#line 4410 "reflect.h2" +#line 4417 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1701,103 +1701,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4416 "reflect.h2" +#line 4423 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4422 "reflect.h2" +#line 4429 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4428 "reflect.h2" +#line 4435 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4435 "reflect.h2" +#line 4442 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4439 "reflect.h2" +#line 4446 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4440 "reflect.h2" +#line 4447 "reflect.h2" }; -#line 4443 "reflect.h2" +#line 4450 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4449 "reflect.h2" +#line 4456 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4456 "reflect.h2" +#line 4463 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4460 "reflect.h2" +#line 4467 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4461 "reflect.h2" +#line 4468 "reflect.h2" }; -#line 4464 "reflect.h2" +#line 4471 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4470 "reflect.h2" +#line 4477 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4474 "reflect.h2" +#line 4481 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4478 "reflect.h2" +#line 4485 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4479 "reflect.h2" +#line 4486 "reflect.h2" }; -#line 4482 "reflect.h2" +#line 4489 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4488 "reflect.h2" +#line 4495 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4495 "reflect.h2" +#line 4502 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4501 "reflect.h2" +#line 4508 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4507 "reflect.h2" +#line 4514 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4515 "reflect.h2" +#line 4522 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1805,10 +1805,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4527 "reflect.h2" +#line 4534 "reflect.h2" }; -#line 4530 "reflect.h2" +#line 4537 "reflect.h2" // // Parse and generation context. // @@ -1824,33 +1824,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4550 "reflect.h2" +#line 4557 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4557 "reflect.h2" +#line 4564 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4569 "reflect.h2" +#line 4576 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4574 "reflect.h2" +#line 4581 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4578 "reflect.h2" +#line 4585 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4592 "reflect.h2" +#line 4599 "reflect.h2" }; -#line 4595 "reflect.h2" +#line 4602 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1863,25 +1863,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4613 "reflect.h2" +#line 4620 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4619 "reflect.h2" +#line 4626 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4626 "reflect.h2" +#line 4633 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4633 "reflect.h2" +#line 4640 "reflect.h2" }; -#line 4636 "reflect.h2" +#line 4643 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1897,7 +1897,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4652 "reflect.h2" +#line 4659 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1905,64 +1905,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4663 "reflect.h2" +#line 4670 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4676 "reflect.h2" +#line 4683 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4684 "reflect.h2" +#line 4691 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4688 "reflect.h2" +#line 4695 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4692 "reflect.h2" +#line 4699 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4704 "reflect.h2" +#line 4711 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4711 "reflect.h2" +#line 4718 "reflect.h2" public: auto next_alternative() & -> void; -#line 4717 "reflect.h2" +#line 4724 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4723 "reflect.h2" +#line 4730 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4727 "reflect.h2" +#line 4734 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4738 "reflect.h2" +#line 4745 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4742 "reflect.h2" +#line 4749 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4748 "reflect.h2" +#line 4755 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4752 "reflect.h2" +#line 4759 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4759 "reflect.h2" +#line 4766 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4770 "reflect.h2" +#line 4777 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1970,51 +1970,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4814 "reflect.h2" +#line 4821 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4826 "reflect.h2" +#line 4833 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4839 "reflect.h2" +#line 4846 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4862 "reflect.h2" +#line 4869 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4879 "reflect.h2" +#line 4886 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4900 "reflect.h2" +#line 4907 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 4910 "reflect.h2" +#line 4917 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 4914 "reflect.h2" +#line 4921 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 4970 "reflect.h2" +#line 4977 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5009 "reflect.h2" +#line 5016 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5024 "reflect.h2" +#line 5031 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2026,10 +2026,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5035 "reflect.h2" +#line 5042 "reflect.h2" }; -#line 5038 "reflect.h2" +#line 5045 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2039,16 +2039,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5052 "reflect.h2" +#line 5059 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5055 "reflect.h2" +#line 5062 "reflect.h2" }; -#line 5058 "reflect.h2" +#line 5065 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2068,68 +2068,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5080 "reflect.h2" +#line 5087 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5086 "reflect.h2" +#line 5093 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5095 "reflect.h2" +#line 5102 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5106 "reflect.h2" +#line 5113 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5113 "reflect.h2" +#line 5120 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5133 "reflect.h2" +#line 5140 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5143 "reflect.h2" +#line 5150 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5166 "reflect.h2" +#line 5173 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5174 "reflect.h2" +#line 5181 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5178 "reflect.h2" +#line 5185 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5184 "reflect.h2" +#line 5191 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5190 "reflect.h2" +#line 5197 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5200 "reflect.h2" +#line 5207 "reflect.h2" public: auto finish_context() & -> void; -#line 5208 "reflect.h2" +#line 5215 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5214 "reflect.h2" +#line 5221 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5218 "reflect.h2" +#line 5225 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5222 "reflect.h2" +#line 5229 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5246 "reflect.h2" +#line 5253 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2137,7 +2137,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5252 "reflect.h2" +#line 5259 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2157,27 +2157,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5271 "reflect.h2" +#line 5278 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5277 "reflect.h2" +#line 5284 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5284 "reflect.h2" +#line 5291 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5301 "reflect.h2" +#line 5308 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5308 "reflect.h2" +#line 5315 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5321 "reflect.h2" +#line 5328 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2185,19 +2185,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5333 "reflect.h2" +#line 5340 "reflect.h2" }; -#line 5336 "reflect.h2" +#line 5343 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5342 "reflect.h2" +#line 5349 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5346 "reflect.h2" +#line 5353 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2205,7 +2205,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5351 "reflect.h2" +#line 5358 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2213,17 +2213,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5359 "reflect.h2" +#line 5366 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5370 "reflect.h2" +#line 5377 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5378 "reflect.h2" +#line 5385 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2231,7 +2231,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5381 "reflect.h2" +#line 5388 "reflect.h2" }; // Regex syntax: a @@ -2239,34 +2239,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5389 "reflect.h2" +#line 5396 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5398 "reflect.h2" +#line 5405 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5404 "reflect.h2" +#line 5411 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5408 "reflect.h2" +#line 5415 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5431 "reflect.h2" +#line 5438 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5452 "reflect.h2" +#line 5459 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5470 "reflect.h2" +#line 5477 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5485 "reflect.h2" +#line 5492 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5491 "reflect.h2" +#line 5498 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2274,33 +2274,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5495 "reflect.h2" +#line 5502 "reflect.h2" }; -#line 5498 "reflect.h2" +#line 5505 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5504 "reflect.h2" +#line 5511 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5516 "reflect.h2" +#line 5523 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5642 "reflect.h2" +#line 5649 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5651 "reflect.h2" +#line 5658 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5656 "reflect.h2" +#line 5663 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2308,20 +2308,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5663 "reflect.h2" +#line 5670 "reflect.h2" }; -#line 5666 "reflect.h2" +#line 5673 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5707 "reflect.h2" +#line 5714 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5718 "reflect.h2" +#line 5725 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2331,20 +2331,20 @@ class class_token class group_ref_token : public regex_token { -#line 5728 "reflect.h2" +#line 5735 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5740 "reflect.h2" +#line 5747 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5841 "reflect.h2" +#line 5848 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5845 "reflect.h2" +#line 5852 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2352,10 +2352,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5848 "reflect.h2" +#line 5855 "reflect.h2" }; -#line 5851 "reflect.h2" +#line 5858 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2369,29 +2369,29 @@ class group_ref_token class group_token : public regex_token { -#line 5865 "reflect.h2" +#line 5872 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5887 "reflect.h2" +#line 5894 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5901 "reflect.h2" +#line 5908 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6060 "reflect.h2" +#line 6067 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6068 "reflect.h2" +#line 6075 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6086 "reflect.h2" +#line 6093 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6117 "reflect.h2" +#line 6124 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2400,25 +2400,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6124 "reflect.h2" +#line 6131 "reflect.h2" }; -#line 6127 "reflect.h2" +#line 6134 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6168 "reflect.h2" +#line 6175 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6188 "reflect.h2" +#line 6195 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6204 "reflect.h2" +#line 6211 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2426,20 +2426,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6212 "reflect.h2" +#line 6219 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6221 "reflect.h2" +#line 6228 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6232 "reflect.h2" +#line 6239 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6239 "reflect.h2" +#line 6246 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2447,26 +2447,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6242 "reflect.h2" +#line 6249 "reflect.h2" }; -#line 6245 "reflect.h2" +#line 6252 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6273 "reflect.h2" +#line 6280 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6301 "reflect.h2" +#line 6308 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6307 "reflect.h2" +#line 6314 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2476,22 +2476,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6387 "reflect.h2" +#line 6394 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6399 "reflect.h2" +#line 6406 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6412 "reflect.h2" +#line 6419 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6431 "reflect.h2" +#line 6438 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6441 "reflect.h2" +#line 6448 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6452 "reflect.h2" +#line 6459 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2499,16 +2499,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6455 "reflect.h2" +#line 6462 "reflect.h2" }; -#line 6458 "reflect.h2" +#line 6465 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6464 "reflect.h2" +#line 6471 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2517,7 +2517,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6494 "reflect.h2" +#line 6501 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2526,14 +2526,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6516 "reflect.h2" +#line 6523 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6538 "reflect.h2" +#line 6545 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2554,24 +2554,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6561 "reflect.h2" +#line 6568 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6596 "reflect.h2" +#line 6603 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6610 "reflect.h2" +#line 6617 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6622 "reflect.h2" +#line 6629 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6677 "reflect.h2" +#line 6684 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2582,7 +2582,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6803 "reflect.h2" +#line 6810 "reflect.h2" } } @@ -6946,67 +6946,74 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return t; } else { - CPP2_UFCS(error)(term, "Do not know how to handle AD for: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + ""); - return "error"; + // Nothing special. A regular expression. + auto expr {term}; + + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + autodiff_expression_handler ad {ctx, t, ":"}; // TODO: get type of expression + ad.pre_traverse(cpp2::move(expr)); + append(cpp2::move(ad)); + + return t; }} } -#line 3786 "reflect.h2" +#line 3793 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 3790 "reflect.h2" +#line 3797 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 3794 "reflect.h2" +#line 3801 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 3798 "reflect.h2" +#line 3805 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 3802 "reflect.h2" +#line 3809 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 3806 "reflect.h2" +#line 3813 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 3810 "reflect.h2" +#line 3817 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 3814 "reflect.h2" +#line 3821 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 3818 "reflect.h2" +#line 3825 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 3822 "reflect.h2" +#line 3829 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 3826 "reflect.h2" +#line 3833 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 3830 "reflect.h2" +#line 3837 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7033,7 +7040,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 3856 "reflect.h2" +#line 3863 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7060,7 +7067,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 3883 "reflect.h2" +#line 3890 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; @@ -7078,19 +7085,19 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3900 "reflect.h2" +#line 3907 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 3908 "reflect.h2" +#line 3915 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) : autodiff_handler_base{ ctx_ }{ -#line 3910 "reflect.h2" +#line 3917 "reflect.h2" } -#line 3912 "reflect.h2" +#line 3919 "reflect.h2" auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7120,7 +7127,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3942 "reflect.h2" +#line 3949 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7160,7 +7167,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -7267,7 +7274,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 3998 "reflect.h2" +#line 4005 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -7632,7 +7639,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4363 "reflect.h2" +#line 4370 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -7648,11 +7655,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4379 "reflect.h2" +#line 4386 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4383 "reflect.h2" +#line 4390 "reflect.h2" // mod: i // mod: m // mod: s @@ -7660,116 +7667,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4392 "reflect.h2" +#line 4399 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4401 "reflect.h2" +#line 4408 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4403 "reflect.h2" +#line 4410 "reflect.h2" } -#line 4405 "reflect.h2" +#line 4412 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4407 "reflect.h2" +#line 4414 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4413 "reflect.h2" +#line 4420 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4414 "reflect.h2" +#line 4421 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4415 "reflect.h2" +#line 4422 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4430 "reflect.h2" +#line 4437 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4433 "reflect.h2" +#line 4440 "reflect.h2" } -#line 4435 "reflect.h2" +#line 4442 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4439 "reflect.h2" +#line 4446 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4451 "reflect.h2" +#line 4458 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4454 "reflect.h2" +#line 4461 "reflect.h2" } -#line 4456 "reflect.h2" +#line 4463 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4460 "reflect.h2" +#line 4467 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4470 "reflect.h2" +#line 4477 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4472 "reflect.h2" +#line 4479 "reflect.h2" } -#line 4474 "reflect.h2" +#line 4481 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4478 "reflect.h2" +#line 4485 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4490 "reflect.h2" +#line 4497 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4493 "reflect.h2" +#line 4500 "reflect.h2" } -#line 4495 "reflect.h2" +#line 4502 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4501 "reflect.h2" +#line 4508 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4507 "reflect.h2" +#line 4514 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7778,7 +7785,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4515 "reflect.h2" +#line 4522 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7794,7 +7801,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4543 "reflect.h2" +#line 4550 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7802,14 +7809,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4551 "reflect.h2" +#line 4558 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4558 "reflect.h2" +#line 4565 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7821,15 +7828,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4570 "reflect.h2" +#line 4577 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4575 "reflect.h2" +#line 4582 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4579 "reflect.h2" +#line 4586 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7850,7 +7857,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4605 "reflect.h2" +#line 4612 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7859,20 +7866,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4614 "reflect.h2" +#line 4621 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4620 "reflect.h2" +#line 4627 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4627 "reflect.h2" +#line 4634 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -7887,16 +7894,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4657 "reflect.h2" +#line 4664 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4661 "reflect.h2" +#line 4668 "reflect.h2" } -#line 4667 "reflect.h2" +#line 4674 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -7906,7 +7913,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4677 "reflect.h2" +#line 4684 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -7914,17 +7921,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4684 "reflect.h2" +#line 4691 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4688 "reflect.h2" +#line 4695 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4695 "reflect.h2" +#line 4702 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -7934,7 +7941,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4704 "reflect.h2" +#line 4711 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -7942,24 +7949,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4711 "reflect.h2" +#line 4718 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4719 "reflect.h2" +#line 4726 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4723 "reflect.h2" +#line 4730 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4727 "reflect.h2" +#line 4734 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -7971,22 +7978,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4738 "reflect.h2" +#line 4745 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4744 "reflect.h2" +#line 4751 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4748 "reflect.h2" +#line 4755 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4752 "reflect.h2" +#line 4759 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -7994,7 +8001,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4759 "reflect.h2" +#line 4766 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8006,10 +8013,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4772 "reflect.h2" +#line 4779 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4775 "reflect.h2" +#line 4782 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8049,7 +8056,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4815 "reflect.h2" +#line 4822 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8061,14 +8068,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4826 "reflect.h2" +#line 4833 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4827 "reflect.h2" +#line 4834 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4828 "reflect.h2" +#line 4835 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4830 "reflect.h2" +#line 4837 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8078,10 +8085,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4839 "reflect.h2" +#line 4846 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4841 "reflect.h2" +#line 4848 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8103,14 +8110,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4862 "reflect.h2" +#line 4869 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4863 "reflect.h2" +#line 4870 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4864 "reflect.h2" +#line 4871 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4866 "reflect.h2" +#line 4873 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8124,7 +8131,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4879 "reflect.h2" +#line 4886 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8146,7 +8153,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4900 "reflect.h2" +#line 4907 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8157,12 +8164,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4910 "reflect.h2" +#line 4917 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 4911 "reflect.h2" +#line 4918 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 4916 "reflect.h2" +#line 4923 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8217,7 +8224,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4970 "reflect.h2" +#line 4977 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8257,7 +8264,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5009 "reflect.h2" +#line 5016 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8273,21 +8280,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5026 "reflect.h2" +#line 5033 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5027 "reflect.h2" +#line 5034 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5028 "reflect.h2" +#line 5035 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5030 "reflect.h2" +#line 5037 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5045 "reflect.h2" +#line 5052 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8295,7 +8302,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5052 "reflect.h2" +#line 5059 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8305,22 +8312,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5070 "reflect.h2" +#line 5077 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5075 "reflect.h2" +#line 5082 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5081 "reflect.h2" +#line 5088 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5087 "reflect.h2" +#line 5094 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8329,7 +8336,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5095 "reflect.h2" +#line 5102 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8341,7 +8348,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5106 "reflect.h2" +#line 5113 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8349,7 +8356,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5113 "reflect.h2" +#line 5120 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8370,7 +8377,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5134 "reflect.h2" +#line 5141 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8380,7 +8387,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5144 "reflect.h2" +#line 5151 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8403,33 +8410,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5168 "reflect.h2" +#line 5175 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5174 "reflect.h2" +#line 5181 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5178 "reflect.h2" +#line 5185 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5184 "reflect.h2" +#line 5191 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5192 "reflect.h2" +#line 5199 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8438,7 +8445,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5200 "reflect.h2" +#line 5207 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8447,22 +8454,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5210 "reflect.h2" +#line 5217 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5214 "reflect.h2" +#line 5221 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5218 "reflect.h2" +#line 5225 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5222 "reflect.h2" +#line 5229 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8486,18 +8493,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5247 "reflect.h2" +#line 5254 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5262 "reflect.h2" +#line 5269 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5264 "reflect.h2" +#line 5271 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8508,15 +8515,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5279 "reflect.h2" +#line 5286 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5282 "reflect.h2" +#line 5289 "reflect.h2" } -#line 5284 "reflect.h2" +#line 5291 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8534,7 +8541,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5301 "reflect.h2" +#line 5308 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8542,7 +8549,7 @@ generation_function_context::generation_function_context(){} } } -#line 5308 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8556,7 +8563,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5321 "reflect.h2" +#line 5328 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8572,14 +8579,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5342 "reflect.h2" +#line 5349 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5344 "reflect.h2" +#line 5351 "reflect.h2" } -#line 5346 "reflect.h2" +#line 5353 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8588,11 +8595,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5361 "reflect.h2" +#line 5368 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5363 "reflect.h2" +#line 5370 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8600,7 +8607,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5370 "reflect.h2" +#line 5377 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8609,37 +8616,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5378 "reflect.h2" +#line 5385 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5392 "reflect.h2" +#line 5399 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5396 "reflect.h2" +#line 5403 "reflect.h2" } -#line 5398 "reflect.h2" +#line 5405 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5402 "reflect.h2" +#line 5409 "reflect.h2" } -#line 5404 "reflect.h2" +#line 5411 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5408 "reflect.h2" +#line 5415 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -8648,14 +8655,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5414 "reflect.h2" +#line 5421 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5419 "reflect.h2" +#line 5426 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8668,7 +8675,7 @@ size_t i{0}; } } -#line 5431 "reflect.h2" +#line 5438 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8690,7 +8697,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5452 "reflect.h2" +#line 5459 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8709,7 +8716,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5470 "reflect.h2" +#line 5477 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8725,14 +8732,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5485 "reflect.h2" +#line 5492 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5491 "reflect.h2" +#line 5498 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8740,19 +8747,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5508 "reflect.h2" +#line 5515 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5509 "reflect.h2" +#line 5516 "reflect.h2" { -#line 5514 "reflect.h2" +#line 5521 "reflect.h2" } -#line 5517 "reflect.h2" +#line 5524 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8878,7 +8885,7 @@ size_t i{0}; ); } -#line 5642 "reflect.h2" +#line 5649 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -8888,13 +8895,13 @@ size_t i{0}; ); } -#line 5651 "reflect.h2" +#line 5658 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5656 "reflect.h2" +#line 5663 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -8905,12 +8912,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5668 "reflect.h2" +#line 5675 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5673 "reflect.h2" +#line 5680 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -8944,7 +8951,7 @@ size_t i{0}; } -#line 5709 "reflect.h2" +#line 5716 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -8953,19 +8960,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5732 "reflect.h2" +#line 5739 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5733 "reflect.h2" +#line 5740 "reflect.h2" { -#line 5738 "reflect.h2" +#line 5745 "reflect.h2" } -#line 5740 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9067,19 +9074,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5841 "reflect.h2" +#line 5848 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5845 "reflect.h2" +#line 5852 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5869 "reflect.h2" +#line 5876 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9098,7 +9105,7 @@ size_t i{0}; return r; } -#line 5887 "reflect.h2" +#line 5894 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9113,7 +9120,7 @@ size_t i{0}; return r; } -#line 5901 "reflect.h2" +#line 5908 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9273,7 +9280,7 @@ size_t i{0}; } } -#line 6060 "reflect.h2" +#line 6067 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9282,7 +9289,7 @@ size_t i{0}; return r; } -#line 6068 "reflect.h2" +#line 6075 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9301,7 +9308,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6086 "reflect.h2" +#line 6093 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9333,7 +9340,7 @@ size_t i{0}; } } -#line 6117 "reflect.h2" +#line 6124 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9344,7 +9351,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6129 "reflect.h2" +#line 6136 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9383,7 +9390,7 @@ size_t i{0}; return r; } -#line 6170 "reflect.h2" +#line 6177 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9401,7 +9408,7 @@ size_t i{0}; }} } -#line 6190 "reflect.h2" +#line 6197 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9415,16 +9422,16 @@ size_t i{0}; } } -#line 6216 "reflect.h2" +#line 6223 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6219 "reflect.h2" +#line 6226 "reflect.h2" } -#line 6221 "reflect.h2" +#line 6228 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9436,7 +9443,7 @@ size_t i{0}; } } -#line 6232 "reflect.h2" +#line 6239 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9444,14 +9451,14 @@ size_t i{0}; return r; } -#line 6239 "reflect.h2" +#line 6246 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6247 "reflect.h2" +#line 6254 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9477,7 +9484,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6275 "reflect.h2" +#line 6282 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9503,11 +9510,11 @@ size_t i{0}; return r; } -#line 6312 "reflect.h2" +#line 6319 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6314 "reflect.h2" +#line 6321 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9581,7 +9588,7 @@ size_t i{0}; return nullptr; } -#line 6387 "reflect.h2" +#line 6394 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9594,7 +9601,7 @@ size_t i{0}; }} } -#line 6399 "reflect.h2" +#line 6406 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9608,7 +9615,7 @@ size_t i{0}; }} } -#line 6412 "reflect.h2" +#line 6419 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9628,7 +9635,7 @@ size_t i{0}; return r; } -#line 6431 "reflect.h2" +#line 6438 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -9639,7 +9646,7 @@ size_t i{0}; return r; } -#line 6441 "reflect.h2" +#line 6448 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9651,14 +9658,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6452 "reflect.h2" +#line 6459 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6464 "reflect.h2" +#line 6471 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9682,7 +9689,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6488 "reflect.h2" +#line 6495 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9692,7 +9699,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6500 "reflect.h2" +#line 6507 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9708,7 +9715,7 @@ size_t i{0}; } } -#line 6520 "reflect.h2" +#line 6527 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9726,15 +9733,15 @@ size_t i{0}; }} } -#line 6556 "reflect.h2" +#line 6563 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6559 "reflect.h2" +#line 6566 "reflect.h2" } -#line 6561 "reflect.h2" +#line 6568 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9770,7 +9777,7 @@ size_t i{0}; return source; } -#line 6596 "reflect.h2" +#line 6603 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9786,7 +9793,7 @@ size_t i{0}; } } -#line 6612 "reflect.h2" +#line 6619 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9795,7 +9802,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9850,7 +9857,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6681 "reflect.h2" +#line 6688 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -9972,7 +9979,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6803 "reflect.h2" +#line 6810 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index f9ca5a68d..f06324be0 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3778,8 +3778,15 @@ autodiff_expression_handler: type = { return t; } else { - term.error( "Do not know how to handle AD for: (term.to_string())$"); - return "error"; + // Nothing special. A regular expression. + expr := term; + + t := ctx*.gen_temporary(); + ad : autodiff_expression_handler = (ctx, t, ":"); // TODO: get type of expression + ad..pre_traverse(expr); + append(ad); + + return t; } } From b3dc8453ea6c63a27deb3720b49bd6b80e5e44d2 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 08:46:09 +0200 Subject: [PATCH 07/54] Handling of function calls. --- regression-tests/pure2-autodiff.cpp2 | 9 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 59 +- .../test-results/pure2-autodiff.cpp2.output | 51 + source/reflect.h | 1276 +++++++++-------- source/reflect.h2 | 54 + 6 files changed, 842 insertions(+), 608 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index c3e6d1f85..c9c22b83f 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -48,6 +48,14 @@ ad_test: @autodiff @print type = { add_mul: (x: double, y: double) -> (r: double) = { r = x + x * y; } + + func: (x: double, y: double) -> (r: double) = { + r = x + y; + } + + func_call: (x: double, y: double) -> (r: double) = { + r = x * func(x, y); + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -73,4 +81,5 @@ main: () = { write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index bc1838275..97dcffd36 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -10,3 +10,4 @@ diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 466b26d0b..d2aabec9a 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -78,6 +78,16 @@ using add_mul_ret = double; #line 48 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; +using func_ret = double; + + +#line 52 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; +using func_call_ret = double; + + +#line 56 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -127,17 +137,25 @@ struct add_mul_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret; +struct func_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret; + +struct func_call_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 51 "pure2-autodiff.cpp2" +#line 59 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 57 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -228,6 +246,20 @@ auto main() -> int; r.construct(x + x * y); return std::move(r.value()); } +#line 52 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ + cpp2::impl::deferred_init r; +#line 53 "pure2-autodiff.cpp2" + r.construct(x + y); + return std::move(r.value()); } + +#line 56 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ + cpp2::impl::deferred_init r; +#line 57 "pure2-autodiff.cpp2" + r.construct(x * func(x, y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y; @@ -298,13 +330,29 @@ auto temp_1_d {x * y_d + y * x_d}; auto temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d);r = x + cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; } +[[nodiscard]] auto ad_test::func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d;r = x + y; + return { std::move(r), std::move(r_d) }; + } +[[nodiscard]] auto ad_test::func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_2 {func_diff(x, x_d, y, y_d)}; + + auto temp_1 {temp_2.r}; + + auto temp_1_d {cpp2::move(temp_2).r_d}; + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } -#line 53 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 57 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -323,6 +371,7 @@ auto main() -> int{ write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 29d6eaa6f..c094ea73a 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -110,6 +110,24 @@ ad_test:/* @autodiff @print */ type = return; } + func:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y; + return; + } + + func_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func(x, y); + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -299,6 +317,39 @@ ad_test:/* @autodiff @print */ type = r = x + temp_1; return; } + + func_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } + + func_call_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_2: _ = func_diff(x, x_d, y, y_d); + temp_1: _ = temp_2.r; + temp_1_d: _ = temp_2.r_d; + r_d = x * temp_1_d + temp_1 * x_d; + r = x * temp_1; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 865a83a75..8254d9e41 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -102,93 +102,93 @@ class value_member_info; #line 2436 "reflect.h2" class simple_traverser; -#line 3715 "reflect.h2" +#line 3721 "reflect.h2" class autodiff_context; -#line 3724 "reflect.h2" +#line 3730 "reflect.h2" class autodiff_handler_base; -#line 3738 "reflect.h2" +#line 3744 "reflect.h2" class autodiff_expression_handler; -#line 3912 "reflect.h2" +#line 3966 "reflect.h2" class autodiff_stmt_handler; -#line 4388 "reflect.h2" +#line 4442 "reflect.h2" class expression_flags; -#line 4404 "reflect.h2" +#line 4458 "reflect.h2" class regex_token; -#line 4431 "reflect.h2" +#line 4485 "reflect.h2" class regex_token_check; -#line 4452 "reflect.h2" +#line 4506 "reflect.h2" class regex_token_code; -#line 4473 "reflect.h2" +#line 4527 "reflect.h2" class regex_token_empty; -#line 4491 "reflect.h2" +#line 4545 "reflect.h2" class regex_token_list; -#line 4543 "reflect.h2" +#line 4597 "reflect.h2" class parse_context_group_state; -#line 4604 "reflect.h2" +#line 4658 "reflect.h2" class parse_context_branch_reset_state; -#line 4647 "reflect.h2" +#line 4701 "reflect.h2" class parse_context; -#line 5048 "reflect.h2" +#line 5102 "reflect.h2" class generation_function_context; -#line 5066 "reflect.h2" +#line 5120 "reflect.h2" class generation_context; -#line 5265 "reflect.h2" +#line 5319 "reflect.h2" class alternative_token; -#line 5280 "reflect.h2" +#line 5334 "reflect.h2" class alternative_token_gen; -#line 5345 "reflect.h2" +#line 5399 "reflect.h2" class any_token; -#line 5362 "reflect.h2" +#line 5416 "reflect.h2" class atomic_group_token; -#line 5392 "reflect.h2" +#line 5446 "reflect.h2" class char_token; -#line 5507 "reflect.h2" +#line 5561 "reflect.h2" class class_token; -#line 5731 "reflect.h2" +#line 5785 "reflect.h2" class group_ref_token; -#line 5868 "reflect.h2" +#line 5922 "reflect.h2" class group_token; -#line 6215 "reflect.h2" +#line 6269 "reflect.h2" class lookahead_lookbehind_token; -#line 6310 "reflect.h2" +#line 6364 "reflect.h2" class range_token; -#line 6467 "reflect.h2" +#line 6521 "reflect.h2" class special_range_token; -#line 6553 "reflect.h2" +#line 6607 "reflect.h2" template class regex_generator; -#line 6810 "reflect.h2" +#line 6864 "reflect.h2" } } @@ -1319,217 +1319,220 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in #line 2436 "reflect.h2" class simple_traverser { + public: virtual auto pre_traverse(cpp2::impl::in expr) -> void; + +#line 2444 "reflect.h2" public: virtual auto traverse(cpp2::impl::in expr) -> void; -#line 2452 "reflect.h2" +#line 2458 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2469 "reflect.h2" +#line 2475 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2480 "reflect.h2" +#line 2486 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2497 "reflect.h2" +#line 2503 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2509 "reflect.h2" +#line 2515 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2526 "reflect.h2" +#line 2532 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2537 "reflect.h2" +#line 2543 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2554 "reflect.h2" +#line 2560 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2565 "reflect.h2" +#line 2571 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2582 "reflect.h2" +#line 2588 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2594 "reflect.h2" +#line 2600 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2611 "reflect.h2" +#line 2617 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2623 "reflect.h2" +#line 2629 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2640 "reflect.h2" +#line 2646 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2651 "reflect.h2" +#line 2657 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2668 "reflect.h2" +#line 2674 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2679 "reflect.h2" +#line 2685 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2696 "reflect.h2" +#line 2702 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2707 "reflect.h2" +#line 2713 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2724 "reflect.h2" +#line 2730 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2735 "reflect.h2" +#line 2741 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2752 "reflect.h2" +#line 2758 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2764 "reflect.h2" +#line 2770 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2781 "reflect.h2" +#line 2787 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2792 "reflect.h2" +#line 2798 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in isas) -> void; -#line 2808 "reflect.h2" +#line 2814 "reflect.h2" public: virtual auto traverse(cpp2::impl::in isas) -> void; -#line 2819 "reflect.h2" +#line 2825 "reflect.h2" public: virtual auto traverse(cpp2::impl::in exprs) -> void; -#line 2826 "reflect.h2" +#line 2832 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in prefix) -> void; -#line 2842 "reflect.h2" +#line 2848 "reflect.h2" public: virtual auto traverse(cpp2::impl::in prefix) -> void; -#line 2847 "reflect.h2" +#line 2853 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in postfix) -> void; -#line 2863 "reflect.h2" +#line 2869 "reflect.h2" public: virtual auto traverse(cpp2::impl::in postfix) -> void; -#line 2882 "reflect.h2" +#line 2888 "reflect.h2" public: virtual auto traverse(cpp2::impl::in uid) -> void; -#line 2888 "reflect.h2" +#line 2894 "reflect.h2" public: virtual auto traverse(cpp2::impl::in qid) -> void; -#line 2898 "reflect.h2" +#line 2904 "reflect.h2" public: virtual auto traverse(cpp2::impl::in tid) -> void; -#line 2915 "reflect.h2" +#line 2921 "reflect.h2" public: virtual auto traverse(cpp2::impl::in primary) -> void; -#line 2935 "reflect.h2" +#line 2941 "reflect.h2" public: virtual auto traverse(cpp2::impl::in idexpr) -> void; public: simple_traverser() = default; public: simple_traverser(simple_traverser const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(simple_traverser const&) -> void = delete; -#line 2950 "reflect.h2" +#line 2956 "reflect.h2" }; -#line 2963 "reflect.h2" +#line 2969 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; -#line 2985 "reflect.h2" +#line 2991 "reflect.h2" auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent = 0) -> void; -#line 3015 "reflect.h2" +#line 3021 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void; -#line 3025 "reflect.h2" +#line 3031 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3035 "reflect.h2" +#line 3041 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3054 "reflect.h2" +#line 3060 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3101 "reflect.h2" +#line 3107 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3118 "reflect.h2" +#line 3124 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3128 "reflect.h2" +#line 3134 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3160 "reflect.h2" +#line 3166 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void; -#line 3171 "reflect.h2" +#line 3177 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3201 "reflect.h2" +#line 3207 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3231 "reflect.h2" +#line 3237 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3261 "reflect.h2" +#line 3267 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3291 "reflect.h2" +#line 3297 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3321 "reflect.h2" +#line 3327 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3351 "reflect.h2" +#line 3357 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3381 "reflect.h2" +#line 3387 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3411 "reflect.h2" +#line 3417 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3441 "reflect.h2" +#line 3447 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3471 "reflect.h2" +#line 3477 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3501 "reflect.h2" +#line 3507 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3531 "reflect.h2" +#line 3537 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void; -#line 3557 "reflect.h2" +#line 3563 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void; -#line 3572 "reflect.h2" +#line 3578 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void; -#line 3596 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void; -#line 3629 "reflect.h2" +#line 3635 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void; -#line 3640 "reflect.h2" +#line 3646 "reflect.h2" auto sample_traverser(cpp2::impl::in qid, cpp2::impl::in indent) -> void; -#line 3656 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void; -#line 3673 "reflect.h2" +#line 3679 "reflect.h2" auto sample_traverser(cpp2::impl::in primary, cpp2::impl::in indent) -> void; -#line 3693 "reflect.h2" +#line 3699 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; -#line 3715 "reflect.h2" +#line 3721 "reflect.h2" class autodiff_context { private: int temporary_count {0}; @@ -1539,7 +1542,7 @@ class autodiff_context { public: auto operator=(autodiff_context const&) -> void = delete; -#line 3722 "reflect.h2" +#line 3728 "reflect.h2" }; class autodiff_handler_base { @@ -1548,21 +1551,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3729 "reflect.h2" +#line 3735 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3733 "reflect.h2" +#line 3739 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3736 "reflect.h2" +#line 3742 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3742 "reflect.h2" +#line 3748 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1571,77 +1574,86 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3755 "reflect.h2" +#line 3761 "reflect.h2" + public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; + +#line 3770 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3793 "reflect.h2" +#line 3808 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 3797 "reflect.h2" +#line 3812 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3801 "reflect.h2" +#line 3816 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3805 "reflect.h2" +#line 3820 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3809 "reflect.h2" +#line 3824 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3813 "reflect.h2" +#line 3828 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3817 "reflect.h2" +#line 3832 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3821 "reflect.h2" +#line 3836 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3825 "reflect.h2" +#line 3840 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3829 "reflect.h2" +#line 3844 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3833 "reflect.h2" +#line 3848 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3837 "reflect.h2" +#line 3852 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3863 "reflect.h2" +#line 3878 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3907 "reflect.h2" +#line 3922 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; + +#line 3926 "reflect.h2" + public: auto traverse(cpp2::impl::in postfix) -> void override; + +#line 3931 "reflect.h2" + public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 3910 "reflect.h2" +#line 3964 "reflect.h2" }; class autodiff_stmt_handler: public autodiff_handler_base { -#line 3915 "reflect.h2" +#line 3969 "reflect.h2" public: autodiff_stmt_handler(autodiff_context* ctx_); -#line 3919 "reflect.h2" +#line 3973 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 3947 "reflect.h2" +#line 4001 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4384 "reflect.h2" +#line 4438 "reflect.h2" using error_func = std::function x)>; -#line 4388 "reflect.h2" +#line 4442 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1676,20 +1688,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4396 "reflect.h2" +#line 4450 "reflect.h2" }; -#line 4404 "reflect.h2" +#line 4458 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4412 "reflect.h2" +#line 4466 "reflect.h2" public: explicit regex_token(); -#line 4417 "reflect.h2" +#line 4471 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1701,103 +1713,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4423 "reflect.h2" +#line 4477 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4429 "reflect.h2" +#line 4483 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4435 "reflect.h2" +#line 4489 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4442 "reflect.h2" +#line 4496 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4446 "reflect.h2" +#line 4500 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4447 "reflect.h2" +#line 4501 "reflect.h2" }; -#line 4450 "reflect.h2" +#line 4504 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4456 "reflect.h2" +#line 4510 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4463 "reflect.h2" +#line 4517 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4467 "reflect.h2" +#line 4521 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4468 "reflect.h2" +#line 4522 "reflect.h2" }; -#line 4471 "reflect.h2" +#line 4525 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4477 "reflect.h2" +#line 4531 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4481 "reflect.h2" +#line 4535 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4485 "reflect.h2" +#line 4539 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4486 "reflect.h2" +#line 4540 "reflect.h2" }; -#line 4489 "reflect.h2" +#line 4543 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4495 "reflect.h2" +#line 4549 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4502 "reflect.h2" +#line 4556 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4508 "reflect.h2" +#line 4562 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4514 "reflect.h2" +#line 4568 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4522 "reflect.h2" +#line 4576 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1805,10 +1817,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4534 "reflect.h2" +#line 4588 "reflect.h2" }; -#line 4537 "reflect.h2" +#line 4591 "reflect.h2" // // Parse and generation context. // @@ -1824,33 +1836,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4557 "reflect.h2" +#line 4611 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4564 "reflect.h2" +#line 4618 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4576 "reflect.h2" +#line 4630 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4581 "reflect.h2" +#line 4635 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4585 "reflect.h2" +#line 4639 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4599 "reflect.h2" +#line 4653 "reflect.h2" }; -#line 4602 "reflect.h2" +#line 4656 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1863,25 +1875,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4620 "reflect.h2" +#line 4674 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4626 "reflect.h2" +#line 4680 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4633 "reflect.h2" +#line 4687 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4640 "reflect.h2" +#line 4694 "reflect.h2" }; -#line 4643 "reflect.h2" +#line 4697 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1897,7 +1909,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4659 "reflect.h2" +#line 4713 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1905,64 +1917,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4670 "reflect.h2" +#line 4724 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4683 "reflect.h2" +#line 4737 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4691 "reflect.h2" +#line 4745 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4695 "reflect.h2" +#line 4749 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4699 "reflect.h2" +#line 4753 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4711 "reflect.h2" +#line 4765 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4718 "reflect.h2" +#line 4772 "reflect.h2" public: auto next_alternative() & -> void; -#line 4724 "reflect.h2" +#line 4778 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4730 "reflect.h2" +#line 4784 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4734 "reflect.h2" +#line 4788 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4745 "reflect.h2" +#line 4799 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4749 "reflect.h2" +#line 4803 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4755 "reflect.h2" +#line 4809 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4759 "reflect.h2" +#line 4813 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4766 "reflect.h2" +#line 4820 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4777 "reflect.h2" +#line 4831 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1970,51 +1982,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4821 "reflect.h2" +#line 4875 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4833 "reflect.h2" +#line 4887 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4846 "reflect.h2" +#line 4900 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4869 "reflect.h2" +#line 4923 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4886 "reflect.h2" +#line 4940 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4907 "reflect.h2" +#line 4961 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 4917 "reflect.h2" +#line 4971 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 4921 "reflect.h2" +#line 4975 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 4977 "reflect.h2" +#line 5031 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5016 "reflect.h2" +#line 5070 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5031 "reflect.h2" +#line 5085 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2026,10 +2038,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5042 "reflect.h2" +#line 5096 "reflect.h2" }; -#line 5045 "reflect.h2" +#line 5099 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2039,16 +2051,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5059 "reflect.h2" +#line 5113 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5062 "reflect.h2" +#line 5116 "reflect.h2" }; -#line 5065 "reflect.h2" +#line 5119 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2068,68 +2080,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5087 "reflect.h2" +#line 5141 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5093 "reflect.h2" +#line 5147 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5102 "reflect.h2" +#line 5156 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5113 "reflect.h2" +#line 5167 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5120 "reflect.h2" +#line 5174 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5140 "reflect.h2" +#line 5194 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5150 "reflect.h2" +#line 5204 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5173 "reflect.h2" +#line 5227 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5181 "reflect.h2" +#line 5235 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5185 "reflect.h2" +#line 5239 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5191 "reflect.h2" +#line 5245 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5197 "reflect.h2" +#line 5251 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5207 "reflect.h2" +#line 5261 "reflect.h2" public: auto finish_context() & -> void; -#line 5215 "reflect.h2" +#line 5269 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5221 "reflect.h2" +#line 5275 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5225 "reflect.h2" +#line 5279 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5229 "reflect.h2" +#line 5283 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5253 "reflect.h2" +#line 5307 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2137,7 +2149,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5259 "reflect.h2" +#line 5313 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2157,27 +2169,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5278 "reflect.h2" +#line 5332 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5284 "reflect.h2" +#line 5338 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5291 "reflect.h2" +#line 5345 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5308 "reflect.h2" +#line 5362 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5315 "reflect.h2" +#line 5369 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5328 "reflect.h2" +#line 5382 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2185,19 +2197,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5340 "reflect.h2" +#line 5394 "reflect.h2" }; -#line 5343 "reflect.h2" +#line 5397 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5349 "reflect.h2" +#line 5403 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5353 "reflect.h2" +#line 5407 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2205,7 +2217,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5358 "reflect.h2" +#line 5412 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2213,17 +2225,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5366 "reflect.h2" +#line 5420 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5377 "reflect.h2" +#line 5431 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5385 "reflect.h2" +#line 5439 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2231,7 +2243,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5388 "reflect.h2" +#line 5442 "reflect.h2" }; // Regex syntax: a @@ -2239,34 +2251,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5396 "reflect.h2" +#line 5450 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5405 "reflect.h2" +#line 5459 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5411 "reflect.h2" +#line 5465 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5415 "reflect.h2" +#line 5469 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5438 "reflect.h2" +#line 5492 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5459 "reflect.h2" +#line 5513 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5477 "reflect.h2" +#line 5531 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5492 "reflect.h2" +#line 5546 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5498 "reflect.h2" +#line 5552 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2274,33 +2286,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5502 "reflect.h2" +#line 5556 "reflect.h2" }; -#line 5505 "reflect.h2" +#line 5559 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5511 "reflect.h2" +#line 5565 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5523 "reflect.h2" +#line 5577 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5649 "reflect.h2" +#line 5703 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5658 "reflect.h2" +#line 5712 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5663 "reflect.h2" +#line 5717 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2308,20 +2320,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5670 "reflect.h2" +#line 5724 "reflect.h2" }; -#line 5673 "reflect.h2" +#line 5727 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5714 "reflect.h2" +#line 5768 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5725 "reflect.h2" +#line 5779 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2331,20 +2343,20 @@ class class_token class group_ref_token : public regex_token { -#line 5735 "reflect.h2" +#line 5789 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5747 "reflect.h2" +#line 5801 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5848 "reflect.h2" +#line 5902 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5852 "reflect.h2" +#line 5906 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2352,10 +2364,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5855 "reflect.h2" +#line 5909 "reflect.h2" }; -#line 5858 "reflect.h2" +#line 5912 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2369,29 +2381,29 @@ class group_ref_token class group_token : public regex_token { -#line 5872 "reflect.h2" +#line 5926 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5894 "reflect.h2" +#line 5948 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5908 "reflect.h2" +#line 5962 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6067 "reflect.h2" +#line 6121 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6075 "reflect.h2" +#line 6129 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6093 "reflect.h2" +#line 6147 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6124 "reflect.h2" +#line 6178 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2400,25 +2412,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6131 "reflect.h2" +#line 6185 "reflect.h2" }; -#line 6134 "reflect.h2" +#line 6188 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6175 "reflect.h2" +#line 6229 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6195 "reflect.h2" +#line 6249 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6211 "reflect.h2" +#line 6265 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2426,20 +2438,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6219 "reflect.h2" +#line 6273 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6228 "reflect.h2" +#line 6282 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6239 "reflect.h2" +#line 6293 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6246 "reflect.h2" +#line 6300 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2447,26 +2459,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6249 "reflect.h2" +#line 6303 "reflect.h2" }; -#line 6252 "reflect.h2" +#line 6306 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6280 "reflect.h2" +#line 6334 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6308 "reflect.h2" +#line 6362 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6314 "reflect.h2" +#line 6368 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2476,22 +2488,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6394 "reflect.h2" +#line 6448 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6406 "reflect.h2" +#line 6460 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6419 "reflect.h2" +#line 6473 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6438 "reflect.h2" +#line 6492 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6448 "reflect.h2" +#line 6502 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6459 "reflect.h2" +#line 6513 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2499,16 +2511,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6462 "reflect.h2" +#line 6516 "reflect.h2" }; -#line 6465 "reflect.h2" +#line 6519 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6471 "reflect.h2" +#line 6525 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2517,7 +2529,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6501 "reflect.h2" +#line 6555 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2526,14 +2538,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6523 "reflect.h2" +#line 6577 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6545 "reflect.h2" +#line 6599 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2554,24 +2566,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6568 "reflect.h2" +#line 6622 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6603 "reflect.h2" +#line 6657 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6617 "reflect.h2" +#line 6671 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6629 "reflect.h2" +#line 6683 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6684 "reflect.h2" +#line 6738 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2582,7 +2594,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6810 "reflect.h2" +#line 6864 "reflect.h2" } } @@ -5525,6 +5537,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } #line 2438 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in expr) -> void + { + // Nothing to select here. + traverse(expr); + } + +#line 2444 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in expr) -> void { // An expression has other shortcuts to query deeper properties, @@ -5538,7 +5557,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in pre_traverse(CPP2_UFCS(as_assignment_expression)(expr)); } -#line 2452 "reflect.h2" +#line 2458 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5556,7 +5575,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2469 "reflect.h2" +#line 2475 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5568,7 +5587,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2480 "reflect.h2" +#line 2486 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5586,7 +5605,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2497 "reflect.h2" +#line 2503 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5598,7 +5617,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2509 "reflect.h2" +#line 2515 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5616,7 +5635,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2526 "reflect.h2" +#line 2532 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5628,7 +5647,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2537 "reflect.h2" +#line 2543 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5646,7 +5665,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2554 "reflect.h2" +#line 2560 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5658,7 +5677,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2565 "reflect.h2" +#line 2571 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5676,7 +5695,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2582 "reflect.h2" +#line 2588 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5688,7 +5707,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2594 "reflect.h2" +#line 2600 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5706,7 +5725,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2611 "reflect.h2" +#line 2617 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5718,7 +5737,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2623 "reflect.h2" +#line 2629 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5736,7 +5755,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2640 "reflect.h2" +#line 2646 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5748,7 +5767,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2651 "reflect.h2" +#line 2657 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5766,7 +5785,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2668 "reflect.h2" +#line 2674 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5778,7 +5797,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2679 "reflect.h2" +#line 2685 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5796,7 +5815,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2696 "reflect.h2" +#line 2702 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5808,7 +5827,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2707 "reflect.h2" +#line 2713 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5826,7 +5845,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2724 "reflect.h2" +#line 2730 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5838,7 +5857,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2735 "reflect.h2" +#line 2741 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5856,7 +5875,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2752 "reflect.h2" +#line 2758 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5868,7 +5887,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2764 "reflect.h2" +#line 2770 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5886,7 +5905,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2781 "reflect.h2" +#line 2787 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5898,7 +5917,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2792 "reflect.h2" +#line 2798 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -5915,7 +5934,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2808 "reflect.h2" +#line 2814 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -5927,7 +5946,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2819 "reflect.h2" +#line 2825 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in exprs) -> void { for ( auto const& expr : CPP2_UFCS(get_expressions)(exprs) ) { @@ -5935,7 +5954,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2826 "reflect.h2" +#line 2832 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -5952,13 +5971,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2842 "reflect.h2" +#line 2848 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in prefix) -> void { pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); } -#line 2847 "reflect.h2" +#line 2853 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -5975,7 +5994,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2863 "reflect.h2" +#line 2869 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -5995,13 +6014,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2882 "reflect.h2" +#line 2888 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in uid) -> void { static_cast(uid); } -#line 2888 "reflect.h2" +#line 2894 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in qid) -> void { for ( @@ -6011,7 +6030,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2898 "reflect.h2" +#line 2904 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in tid) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6028,7 +6047,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 2915 "reflect.h2" +#line 2921 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6048,7 +6067,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}}} } -#line 2935 "reflect.h2" +#line 2941 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in idexpr) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6065,7 +6084,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 2953 "reflect.h2" +#line 2959 "reflect.h2" //----------------------------------------------------------------------- // // sample_traverser serves two purposes: @@ -6076,7 +6095,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // for reflecting on function bodies (statements, expressions) // -#line 2963 "reflect.h2" +#line 2969 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void { sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); @@ -6098,7 +6117,7 @@ auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in f, cpp2::impl::in indent) -> void { sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); @@ -6128,7 +6147,7 @@ auto sample_traverser(cpp2::impl::in f, cpp2::impl:: } } -#line 3015 "reflect.h2" +#line 3021 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void { sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); @@ -6138,7 +6157,7 @@ auto sample_traverser(cpp2::impl::in o, cpp2::impl::in } } -#line 3025 "reflect.h2" +#line 3031 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); @@ -6148,7 +6167,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("parameter:", indent); @@ -6167,7 +6186,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl: sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); } -#line 3054 "reflect.h2" +#line 3060 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6214,7 +6233,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in stmt, cpp2::impl::in indent) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6231,7 +6250,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl: } } -#line 3118 "reflect.h2" +#line 3124 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { sample_print("return statement", indent); @@ -6241,7 +6260,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::i } } -#line 3128 "reflect.h2" +#line 3134 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6273,7 +6292,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl } } -#line 3160 "reflect.h2" +#line 3166 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void { // An expression has other shortcuts to query deeper properties, @@ -6284,7 +6303,7 @@ auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6302,7 +6321,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3187 "reflect.h2" +#line 3193 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6314,11 +6333,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3197 "reflect.h2" +#line 3203 "reflect.h2" } } -#line 3201 "reflect.h2" +#line 3207 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6336,7 +6355,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3217 "reflect.h2" +#line 3223 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6348,11 +6367,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3227 "reflect.h2" +#line 3233 "reflect.h2" } } -#line 3231 "reflect.h2" +#line 3237 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6370,7 +6389,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2 { auto first{true}; -#line 3247 "reflect.h2" +#line 3253 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6382,11 +6401,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3257 "reflect.h2" +#line 3263 "reflect.h2" } } -#line 3261 "reflect.h2" +#line 3267 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6404,7 +6423,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::imp { auto first{true}; -#line 3277 "reflect.h2" +#line 3283 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6416,11 +6435,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3287 "reflect.h2" +#line 3293 "reflect.h2" } } -#line 3291 "reflect.h2" +#line 3297 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6438,7 +6457,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3307 "reflect.h2" +#line 3313 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6450,11 +6469,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3317 "reflect.h2" +#line 3323 "reflect.h2" } } -#line 3321 "reflect.h2" +#line 3327 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6472,7 +6491,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3337 "reflect.h2" +#line 3343 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6484,11 +6503,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3347 "reflect.h2" +#line 3353 "reflect.h2" } } -#line 3351 "reflect.h2" +#line 3357 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6506,7 +6525,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3367 "reflect.h2" +#line 3373 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6518,11 +6537,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3377 "reflect.h2" +#line 3383 "reflect.h2" } } -#line 3381 "reflect.h2" +#line 3387 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6540,7 +6559,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3397 "reflect.h2" +#line 3403 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6552,11 +6571,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3407 "reflect.h2" +#line 3413 "reflect.h2" } } -#line 3411 "reflect.h2" +#line 3417 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6574,7 +6593,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3427 "reflect.h2" +#line 3433 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6586,11 +6605,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3437 "reflect.h2" +#line 3443 "reflect.h2" } } -#line 3441 "reflect.h2" +#line 3447 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6608,7 +6627,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl { auto first{true}; -#line 3457 "reflect.h2" +#line 3463 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6620,11 +6639,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3467 "reflect.h2" +#line 3473 "reflect.h2" } } -#line 3471 "reflect.h2" +#line 3477 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6642,7 +6661,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3487 "reflect.h2" +#line 3493 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6654,11 +6673,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3497 "reflect.h2" +#line 3503 "reflect.h2" } } -#line 3501 "reflect.h2" +#line 3507 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6676,7 +6695,7 @@ auto sample_traverser(cpp2::impl::in binexpr, c { auto first{true}; -#line 3517 "reflect.h2" +#line 3523 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6688,11 +6707,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3527 "reflect.h2" +#line 3533 "reflect.h2" } } -#line 3531 "reflect.h2" +#line 3537 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6718,7 +6737,7 @@ auto sample_traverser(cpp2::impl::in isas, cpp2::impl::i } } -#line 3557 "reflect.h2" +#line 3563 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_empty)(exprs)) { @@ -6733,7 +6752,7 @@ auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::i } } -#line 3572 "reflect.h2" +#line 3578 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -6757,7 +6776,7 @@ auto sample_traverser(cpp2::impl::in prefix, cpp2::impl } } -#line 3596 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6790,7 +6809,7 @@ auto sample_traverser(cpp2::impl::in postfix, cpp2::im } } -#line 3629 "reflect.h2" +#line 3635 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(uid)) { @@ -6801,13 +6820,13 @@ auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in qid, cpp2::impl::in indent) -> void { { auto first{true}; -#line 3643 "reflect.h2" +#line 3649 "reflect.h2" for ( auto const& term : CPP2_UFCS(get_terms)(qid) ) { @@ -6819,10 +6838,10 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_unqualified)(term), indent + 2); } } -#line 3653 "reflect.h2" +#line 3659 "reflect.h2" } -#line 3656 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6839,7 +6858,7 @@ auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in primary, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6859,7 +6878,7 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im }}}} } -#line 3693 "reflect.h2" +#line 3699 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6876,39 +6895,39 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}} } -#line 3710 "reflect.h2" +#line 3716 "reflect.h2" //----------------------------------------------------------------------- // // autodiff - stub // -#line 3718 "reflect.h2" +#line 3724 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 3729 "reflect.h2" +#line 3735 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3731 "reflect.h2" +#line 3737 "reflect.h2" } -#line 3729 "reflect.h2" +#line 3735 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3731 "reflect.h2" +#line 3737 "reflect.h2" } -#line 3733 "reflect.h2" +#line 3739 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 3748 "reflect.h2" +#line 3754 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -6916,10 +6935,20 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_ } , declare_d{ declare_ }{ -#line 3753 "reflect.h2" +#line 3759 "reflect.h2" } -#line 3755 "reflect.h2" +#line 3761 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ + std::vector args {}; + for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { + CPP2_UFCS(push_back)(args, handle_expression_term(expr)); + } + + return args; + } + +#line 3770 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -6958,62 +6987,62 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 3793 "reflect.h2" +#line 3808 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 3797 "reflect.h2" +#line 3812 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 3801 "reflect.h2" +#line 3816 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 3805 "reflect.h2" +#line 3820 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 3809 "reflect.h2" +#line 3824 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 3813 "reflect.h2" +#line 3828 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 3817 "reflect.h2" +#line 3832 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 3821 "reflect.h2" +#line 3836 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 3825 "reflect.h2" +#line 3840 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 3829 "reflect.h2" +#line 3844 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 3833 "reflect.h2" +#line 3848 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 3837 "reflect.h2" +#line 3852 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7040,7 +7069,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 3863 "reflect.h2" +#line 3878 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7067,7 +7096,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 3890 "reflect.h2" +#line 3905 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; @@ -7085,19 +7114,60 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3907 "reflect.h2" +#line 3922 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 3915 "reflect.h2" +#line 3926 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void + { + CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); + } + +#line 3931 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void + { + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + // Check for function call, everything else is not handled. + if (CPP2_UFCS(ssize)(terms) != 1 && CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)) != "(") { + CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + return ; + } + + // First handle all arguments + auto term {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(terms), 0)}; + std::vector args {}; + if (CPP2_UFCS(is_expression_list)(term)) { + args = handle_expression_list(CPP2_UFCS(get_expression_list)(cpp2::move(term))); + } + else { + CPP2_UFCS(push_back)(args, handle_expression_term(CPP2_UFCS(get_expression)(cpp2::move(term)))); + } + + // All arguments have now been handled. Form the function call + auto ret_temp {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + diff += "" + cpp2::to_string(ret_temp) + " := " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))) + "_diff("; + for ( auto const& arg : cpp2::move(args) ) { + diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; + } + diff += ");\n"; + + // Copy the return values + // TODO: Look up return value name of function. + diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(ret_temp) + ".r;\n"; + diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(cpp2::move(ret_temp)) + ".r_d;\n"; + } + +#line 3969 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) : autodiff_handler_base{ ctx_ }{ -#line 3917 "reflect.h2" +#line 3971 "reflect.h2" } -#line 3919 "reflect.h2" +#line 3973 "reflect.h2" auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7127,7 +7197,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3949 "reflect.h2" +#line 4003 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7167,7 +7237,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 3989 "reflect.h2" +#line 4043 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -7274,7 +7344,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4005 "reflect.h2" +#line 4059 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -7639,7 +7709,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4370 "reflect.h2" +#line 4424 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -7655,11 +7725,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4386 "reflect.h2" +#line 4440 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4390 "reflect.h2" +#line 4444 "reflect.h2" // mod: i // mod: m // mod: s @@ -7667,116 +7737,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4399 "reflect.h2" +#line 4453 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4408 "reflect.h2" +#line 4462 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4410 "reflect.h2" +#line 4464 "reflect.h2" } -#line 4412 "reflect.h2" +#line 4466 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4414 "reflect.h2" +#line 4468 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4420 "reflect.h2" +#line 4474 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4421 "reflect.h2" +#line 4475 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4422 "reflect.h2" +#line 4476 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4437 "reflect.h2" +#line 4491 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4440 "reflect.h2" +#line 4494 "reflect.h2" } -#line 4442 "reflect.h2" +#line 4496 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4446 "reflect.h2" +#line 4500 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4458 "reflect.h2" +#line 4512 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4461 "reflect.h2" +#line 4515 "reflect.h2" } -#line 4463 "reflect.h2" +#line 4517 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4467 "reflect.h2" +#line 4521 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4477 "reflect.h2" +#line 4531 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4479 "reflect.h2" +#line 4533 "reflect.h2" } -#line 4481 "reflect.h2" +#line 4535 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4485 "reflect.h2" +#line 4539 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4497 "reflect.h2" +#line 4551 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4500 "reflect.h2" +#line 4554 "reflect.h2" } -#line 4502 "reflect.h2" +#line 4556 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4508 "reflect.h2" +#line 4562 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4514 "reflect.h2" +#line 4568 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7785,7 +7855,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4522 "reflect.h2" +#line 4576 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7801,7 +7871,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4550 "reflect.h2" +#line 4604 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7809,14 +7879,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4558 "reflect.h2" +#line 4612 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4565 "reflect.h2" +#line 4619 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7828,15 +7898,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4577 "reflect.h2" +#line 4631 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4582 "reflect.h2" +#line 4636 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4586 "reflect.h2" +#line 4640 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7857,7 +7927,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4612 "reflect.h2" +#line 4666 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7866,20 +7936,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4621 "reflect.h2" +#line 4675 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4627 "reflect.h2" +#line 4681 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4634 "reflect.h2" +#line 4688 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -7894,16 +7964,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4664 "reflect.h2" +#line 4718 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4668 "reflect.h2" +#line 4722 "reflect.h2" } -#line 4674 "reflect.h2" +#line 4728 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -7913,7 +7983,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4684 "reflect.h2" +#line 4738 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -7921,17 +7991,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4691 "reflect.h2" +#line 4745 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4695 "reflect.h2" +#line 4749 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4702 "reflect.h2" +#line 4756 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -7941,7 +8011,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4711 "reflect.h2" +#line 4765 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -7949,24 +8019,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4718 "reflect.h2" +#line 4772 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4726 "reflect.h2" +#line 4780 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4730 "reflect.h2" +#line 4784 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4734 "reflect.h2" +#line 4788 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -7978,22 +8048,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4745 "reflect.h2" +#line 4799 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4751 "reflect.h2" +#line 4805 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4755 "reflect.h2" +#line 4809 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4759 "reflect.h2" +#line 4813 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8001,7 +8071,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4766 "reflect.h2" +#line 4820 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8013,10 +8083,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4779 "reflect.h2" +#line 4833 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4782 "reflect.h2" +#line 4836 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8056,7 +8126,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4822 "reflect.h2" +#line 4876 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8068,14 +8138,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4833 "reflect.h2" +#line 4887 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4834 "reflect.h2" +#line 4888 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4835 "reflect.h2" +#line 4889 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4837 "reflect.h2" +#line 4891 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8085,10 +8155,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4846 "reflect.h2" +#line 4900 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4848 "reflect.h2" +#line 4902 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8110,14 +8180,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4869 "reflect.h2" +#line 4923 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4870 "reflect.h2" +#line 4924 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4871 "reflect.h2" +#line 4925 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4873 "reflect.h2" +#line 4927 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8131,7 +8201,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4886 "reflect.h2" +#line 4940 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8153,7 +8223,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4907 "reflect.h2" +#line 4961 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8164,12 +8234,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4917 "reflect.h2" +#line 4971 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 4918 "reflect.h2" +#line 4972 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 4923 "reflect.h2" +#line 4977 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8224,7 +8294,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 4977 "reflect.h2" +#line 5031 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8264,7 +8334,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5016 "reflect.h2" +#line 5070 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8280,21 +8350,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5033 "reflect.h2" +#line 5087 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5034 "reflect.h2" +#line 5088 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5035 "reflect.h2" +#line 5089 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5037 "reflect.h2" +#line 5091 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5052 "reflect.h2" +#line 5106 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8302,7 +8372,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5059 "reflect.h2" +#line 5113 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8312,22 +8382,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5077 "reflect.h2" +#line 5131 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5082 "reflect.h2" +#line 5136 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5088 "reflect.h2" +#line 5142 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5094 "reflect.h2" +#line 5148 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8336,7 +8406,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5102 "reflect.h2" +#line 5156 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8348,7 +8418,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5113 "reflect.h2" +#line 5167 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8356,7 +8426,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5120 "reflect.h2" +#line 5174 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8377,7 +8447,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5141 "reflect.h2" +#line 5195 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8387,7 +8457,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5151 "reflect.h2" +#line 5205 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8410,33 +8480,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5175 "reflect.h2" +#line 5229 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5181 "reflect.h2" +#line 5235 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5185 "reflect.h2" +#line 5239 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5191 "reflect.h2" +#line 5245 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5199 "reflect.h2" +#line 5253 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8445,7 +8515,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5207 "reflect.h2" +#line 5261 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8454,22 +8524,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5217 "reflect.h2" +#line 5271 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5221 "reflect.h2" +#line 5275 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5225 "reflect.h2" +#line 5279 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5229 "reflect.h2" +#line 5283 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8493,18 +8563,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5254 "reflect.h2" +#line 5308 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5269 "reflect.h2" +#line 5323 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5271 "reflect.h2" +#line 5325 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8515,15 +8585,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5286 "reflect.h2" +#line 5340 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5289 "reflect.h2" +#line 5343 "reflect.h2" } -#line 5291 "reflect.h2" +#line 5345 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8541,7 +8611,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5308 "reflect.h2" +#line 5362 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8549,7 +8619,7 @@ generation_function_context::generation_function_context(){} } } -#line 5315 "reflect.h2" +#line 5369 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8563,7 +8633,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5328 "reflect.h2" +#line 5382 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8579,14 +8649,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5349 "reflect.h2" +#line 5403 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5351 "reflect.h2" +#line 5405 "reflect.h2" } -#line 5353 "reflect.h2" +#line 5407 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8595,11 +8665,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5368 "reflect.h2" +#line 5422 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5370 "reflect.h2" +#line 5424 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8607,7 +8677,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5377 "reflect.h2" +#line 5431 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8616,37 +8686,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5385 "reflect.h2" +#line 5439 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5399 "reflect.h2" +#line 5453 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5403 "reflect.h2" +#line 5457 "reflect.h2" } -#line 5405 "reflect.h2" +#line 5459 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5409 "reflect.h2" +#line 5463 "reflect.h2" } -#line 5411 "reflect.h2" +#line 5465 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5415 "reflect.h2" +#line 5469 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -8655,14 +8725,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5421 "reflect.h2" +#line 5475 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5426 "reflect.h2" +#line 5480 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8675,7 +8745,7 @@ size_t i{0}; } } -#line 5438 "reflect.h2" +#line 5492 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8697,7 +8767,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5459 "reflect.h2" +#line 5513 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8716,7 +8786,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5477 "reflect.h2" +#line 5531 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8732,14 +8802,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5492 "reflect.h2" +#line 5546 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5498 "reflect.h2" +#line 5552 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8747,19 +8817,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5515 "reflect.h2" +#line 5569 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5516 "reflect.h2" +#line 5570 "reflect.h2" { -#line 5521 "reflect.h2" +#line 5575 "reflect.h2" } -#line 5524 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8885,7 +8955,7 @@ size_t i{0}; ); } -#line 5649 "reflect.h2" +#line 5703 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -8895,13 +8965,13 @@ size_t i{0}; ); } -#line 5658 "reflect.h2" +#line 5712 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5663 "reflect.h2" +#line 5717 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -8912,12 +8982,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5675 "reflect.h2" +#line 5729 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5680 "reflect.h2" +#line 5734 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -8951,7 +9021,7 @@ size_t i{0}; } -#line 5716 "reflect.h2" +#line 5770 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -8960,19 +9030,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5739 "reflect.h2" +#line 5793 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5740 "reflect.h2" +#line 5794 "reflect.h2" { -#line 5745 "reflect.h2" +#line 5799 "reflect.h2" } -#line 5747 "reflect.h2" +#line 5801 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9074,19 +9144,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5848 "reflect.h2" +#line 5902 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5852 "reflect.h2" +#line 5906 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5876 "reflect.h2" +#line 5930 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9105,7 +9175,7 @@ size_t i{0}; return r; } -#line 5894 "reflect.h2" +#line 5948 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9120,7 +9190,7 @@ size_t i{0}; return r; } -#line 5908 "reflect.h2" +#line 5962 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9280,7 +9350,7 @@ size_t i{0}; } } -#line 6067 "reflect.h2" +#line 6121 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9289,7 +9359,7 @@ size_t i{0}; return r; } -#line 6075 "reflect.h2" +#line 6129 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9308,7 +9378,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6093 "reflect.h2" +#line 6147 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9340,7 +9410,7 @@ size_t i{0}; } } -#line 6124 "reflect.h2" +#line 6178 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9351,7 +9421,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6136 "reflect.h2" +#line 6190 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9390,7 +9460,7 @@ size_t i{0}; return r; } -#line 6177 "reflect.h2" +#line 6231 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9408,7 +9478,7 @@ size_t i{0}; }} } -#line 6197 "reflect.h2" +#line 6251 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9422,16 +9492,16 @@ size_t i{0}; } } -#line 6223 "reflect.h2" +#line 6277 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6226 "reflect.h2" +#line 6280 "reflect.h2" } -#line 6228 "reflect.h2" +#line 6282 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9443,7 +9513,7 @@ size_t i{0}; } } -#line 6239 "reflect.h2" +#line 6293 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9451,14 +9521,14 @@ size_t i{0}; return r; } -#line 6246 "reflect.h2" +#line 6300 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6254 "reflect.h2" +#line 6308 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9484,7 +9554,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6282 "reflect.h2" +#line 6336 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9510,11 +9580,11 @@ size_t i{0}; return r; } -#line 6319 "reflect.h2" +#line 6373 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6321 "reflect.h2" +#line 6375 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9588,7 +9658,7 @@ size_t i{0}; return nullptr; } -#line 6394 "reflect.h2" +#line 6448 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9601,7 +9671,7 @@ size_t i{0}; }} } -#line 6406 "reflect.h2" +#line 6460 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9615,7 +9685,7 @@ size_t i{0}; }} } -#line 6419 "reflect.h2" +#line 6473 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9635,7 +9705,7 @@ size_t i{0}; return r; } -#line 6438 "reflect.h2" +#line 6492 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -9646,7 +9716,7 @@ size_t i{0}; return r; } -#line 6448 "reflect.h2" +#line 6502 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9658,14 +9728,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6459 "reflect.h2" +#line 6513 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6471 "reflect.h2" +#line 6525 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9689,7 +9759,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6495 "reflect.h2" +#line 6549 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9699,7 +9769,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6507 "reflect.h2" +#line 6561 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9715,7 +9785,7 @@ size_t i{0}; } } -#line 6527 "reflect.h2" +#line 6581 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9733,15 +9803,15 @@ size_t i{0}; }} } -#line 6563 "reflect.h2" +#line 6617 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6566 "reflect.h2" +#line 6620 "reflect.h2" } -#line 6568 "reflect.h2" +#line 6622 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9777,7 +9847,7 @@ size_t i{0}; return source; } -#line 6603 "reflect.h2" +#line 6657 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9793,7 +9863,7 @@ size_t i{0}; } } -#line 6619 "reflect.h2" +#line 6673 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9802,7 +9872,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9857,7 +9927,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6688 "reflect.h2" +#line 6742 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -9979,7 +10049,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6810 "reflect.h2" +#line 6864 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index f06324be0..c780463d5 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -2435,6 +2435,12 @@ sample_print: (s: std::string_view, indent: i32) = simple_traverser: type = { + pre_traverse: (virtual inout this, expr: meta::expression) = + { + // Nothing to select here. + traverse(expr); + } + traverse: (virtual inout this, expr: meta::expression) = { // An expression has other shortcuts to query deeper properties, @@ -3752,6 +3758,15 @@ autodiff_expression_handler: type = { declare_d = declare_; } + handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { + args : std::vector = (); + for list.get_expressions() do (expr) { + args.push_back(handle_expression_term(expr)); + } + + return args; + } + handle_expression_term :(inout this, term) -> std::string = { if term.is_identifier() { return term.to_string(); @@ -3907,6 +3922,45 @@ autodiff_expression_handler: type = { traverse: (override inout this, isas: meta::is_as_expression) = { isas.error( "AD: Is as expressions are not yet handled." ); } + + traverse: (override inout this, postfix: meta::prefix_expression) = + { + postfix.error( "AD: Prefix expressions are not yet handled." ); + } + + traverse: (override inout this, postfix: meta::postfix_expression) = + { + terms := postfix.get_terms(); + + // Check for function call, everything else is not handled. + if terms.ssize() != 1 && terms[0].get_op() != "(" { + postfix.error( "AD: Postfix expressions are only handled for function calls. Do not know how to handle: (postfix.to_string())$" ); + return; + } + + // First handle all arguments + term := terms[0]; + args : std::vector = (); + if term.is_expression_list() { + args = handle_expression_list(term.get_expression_list()); + } + else { + args.push_back(handle_expression_term(term.get_expression())); + } + + // All arguments have now been handled. Form the function call + ret_temp := ctx*.gen_temporary(); + diff += "(ret_temp)$ := (postfix.get_primary_expression().to_string())$_diff("; + for args do (arg) { + diff += "(arg)$, (arg)$_d,"; + } + diff += ");\n"; + + // Copy the return values + // TODO: Look up return value name of function. + diff += "(lhs)$ (declare_p)$= (ret_temp)$.r;\n"; + diff += "(lhs)$_d (declare_d)$= (ret_temp)$.r_d;\n"; + } } autodiff_stmt_handler: type = { From 358226d51da2313d114168d59fe80903b287a314 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 09:11:20 +0200 Subject: [PATCH 08/54] Added special handling of math functions. --- regression-tests/pure2-autodiff.cpp2 | 5 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 35 +- .../test-results/pure2-autodiff.cpp2.output | 26 + source/reflect.h | 928 +++++++++--------- source/reflect.h2 | 34 +- 6 files changed, 578 insertions(+), 451 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index c9c22b83f..279d100b6 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -56,6 +56,10 @@ ad_test: @autodiff @print type = { func_call: (x: double, y: double) -> (r: double) = { r = x * func(x, y); } + + sin_call: (x: double, y: double) -> (r: double) = { + r = sin(x - y); + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -82,4 +86,5 @@ main: () = { write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); + write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 97dcffd36..90af526c2 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -11,3 +11,4 @@ diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(sin(x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index d2aabec9a..e85aa940a 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -88,6 +88,11 @@ using func_call_ret = double; #line 56 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; +using sin_call_ret = double; + + +#line 60 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -145,17 +150,21 @@ struct func_call_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret; +struct sin_call_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 59 "pure2-autodiff.cpp2" +#line 63 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -260,6 +269,13 @@ auto main() -> int; r.construct(x * func(x, y)); return std::move(r.value()); } +#line 60 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ + cpp2::impl::deferred_init r; +#line 61 "pure2-autodiff.cpp2" + r.construct(sin(x - y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y; @@ -347,12 +363,20 @@ auto temp_2 {func_diff(x, x_d, y, y_d)}; return { std::move(r), std::move(r_d) }; } -#line 61 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x_d - y_d}; +auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); + r = sin(cpp2::move(temp_1)); + return { std::move(r), std::move(r_d) }; } + +#line 65 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -372,6 +396,7 @@ auto main() -> int{ write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); + write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index c094ea73a..692e7fba9 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -128,6 +128,15 @@ ad_test:/* @autodiff @print */ type = return; } + sin_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = sin(x - y); + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -350,6 +359,23 @@ ad_test:/* @autodiff @print */ type = r = x * temp_1; return; } + + sin_call_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: _ = x_d - y_d; + temp_1: _ = x - y; + r_d = cos(temp_1) * temp_1_d; + r = sin(temp_1); + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 8254d9e41..93f9bb402 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -106,89 +106,89 @@ class simple_traverser; class autodiff_context; -#line 3730 "reflect.h2" +#line 3736 "reflect.h2" class autodiff_handler_base; -#line 3744 "reflect.h2" +#line 3750 "reflect.h2" class autodiff_expression_handler; -#line 3966 "reflect.h2" +#line 3998 "reflect.h2" class autodiff_stmt_handler; -#line 4442 "reflect.h2" +#line 4474 "reflect.h2" class expression_flags; -#line 4458 "reflect.h2" +#line 4490 "reflect.h2" class regex_token; -#line 4485 "reflect.h2" +#line 4517 "reflect.h2" class regex_token_check; -#line 4506 "reflect.h2" +#line 4538 "reflect.h2" class regex_token_code; -#line 4527 "reflect.h2" +#line 4559 "reflect.h2" class regex_token_empty; -#line 4545 "reflect.h2" +#line 4577 "reflect.h2" class regex_token_list; -#line 4597 "reflect.h2" +#line 4629 "reflect.h2" class parse_context_group_state; -#line 4658 "reflect.h2" +#line 4690 "reflect.h2" class parse_context_branch_reset_state; -#line 4701 "reflect.h2" +#line 4733 "reflect.h2" class parse_context; -#line 5102 "reflect.h2" +#line 5134 "reflect.h2" class generation_function_context; -#line 5120 "reflect.h2" +#line 5152 "reflect.h2" class generation_context; -#line 5319 "reflect.h2" +#line 5351 "reflect.h2" class alternative_token; -#line 5334 "reflect.h2" +#line 5366 "reflect.h2" class alternative_token_gen; -#line 5399 "reflect.h2" +#line 5431 "reflect.h2" class any_token; -#line 5416 "reflect.h2" +#line 5448 "reflect.h2" class atomic_group_token; -#line 5446 "reflect.h2" +#line 5478 "reflect.h2" class char_token; -#line 5561 "reflect.h2" +#line 5593 "reflect.h2" class class_token; -#line 5785 "reflect.h2" +#line 5817 "reflect.h2" class group_ref_token; -#line 5922 "reflect.h2" +#line 5954 "reflect.h2" class group_token; -#line 6269 "reflect.h2" +#line 6301 "reflect.h2" class lookahead_lookbehind_token; -#line 6364 "reflect.h2" +#line 6396 "reflect.h2" class range_token; -#line 6521 "reflect.h2" +#line 6553 "reflect.h2" class special_range_token; -#line 6607 "reflect.h2" +#line 6639 "reflect.h2" template class regex_generator; -#line 6864 "reflect.h2" +#line 6896 "reflect.h2" } } @@ -1535,14 +1535,19 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 3721 "reflect.h2" class autodiff_context { private: int temporary_count {0}; + public: std::map math_funcs { + std::make_pair("sin", "cos(_x_)"), + std::make_pair("cos", "-sin(_x_)"), + std::make_pair("exp", "exp(_x_)")}; +#line 3730 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3728 "reflect.h2" +#line 3734 "reflect.h2" }; class autodiff_handler_base { @@ -1551,21 +1556,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3735 "reflect.h2" +#line 3741 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3739 "reflect.h2" +#line 3745 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3742 "reflect.h2" +#line 3748 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3748 "reflect.h2" +#line 3754 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1574,86 +1579,89 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3761 "reflect.h2" +#line 3767 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 3770 "reflect.h2" +#line 3776 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3808 "reflect.h2" +#line 3814 "reflect.h2" + public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; + +#line 3829 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 3812 "reflect.h2" +#line 3833 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3816 "reflect.h2" +#line 3837 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3820 "reflect.h2" +#line 3841 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3824 "reflect.h2" +#line 3845 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3828 "reflect.h2" +#line 3849 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3832 "reflect.h2" +#line 3853 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3836 "reflect.h2" +#line 3857 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3840 "reflect.h2" +#line 3861 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3844 "reflect.h2" +#line 3865 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3848 "reflect.h2" +#line 3869 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3852 "reflect.h2" +#line 3873 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3878 "reflect.h2" +#line 3899 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3922 "reflect.h2" +#line 3943 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 3926 "reflect.h2" +#line 3947 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 3931 "reflect.h2" +#line 3952 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 3964 "reflect.h2" +#line 3996 "reflect.h2" }; class autodiff_stmt_handler: public autodiff_handler_base { -#line 3969 "reflect.h2" +#line 4001 "reflect.h2" public: autodiff_stmt_handler(autodiff_context* ctx_); -#line 3973 "reflect.h2" +#line 4005 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4001 "reflect.h2" +#line 4033 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4438 "reflect.h2" +#line 4470 "reflect.h2" using error_func = std::function x)>; -#line 4442 "reflect.h2" +#line 4474 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1688,20 +1696,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4450 "reflect.h2" +#line 4482 "reflect.h2" }; -#line 4458 "reflect.h2" +#line 4490 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4466 "reflect.h2" +#line 4498 "reflect.h2" public: explicit regex_token(); -#line 4471 "reflect.h2" +#line 4503 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1713,103 +1721,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4477 "reflect.h2" +#line 4509 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4483 "reflect.h2" +#line 4515 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4489 "reflect.h2" +#line 4521 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4496 "reflect.h2" +#line 4528 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4500 "reflect.h2" +#line 4532 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4501 "reflect.h2" +#line 4533 "reflect.h2" }; -#line 4504 "reflect.h2" +#line 4536 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4510 "reflect.h2" +#line 4542 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4517 "reflect.h2" +#line 4549 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4521 "reflect.h2" +#line 4553 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4522 "reflect.h2" +#line 4554 "reflect.h2" }; -#line 4525 "reflect.h2" +#line 4557 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4531 "reflect.h2" +#line 4563 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4535 "reflect.h2" +#line 4567 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4539 "reflect.h2" +#line 4571 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4540 "reflect.h2" +#line 4572 "reflect.h2" }; -#line 4543 "reflect.h2" +#line 4575 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4549 "reflect.h2" +#line 4581 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4556 "reflect.h2" +#line 4588 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4562 "reflect.h2" +#line 4594 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4568 "reflect.h2" +#line 4600 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4576 "reflect.h2" +#line 4608 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1817,10 +1825,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4588 "reflect.h2" +#line 4620 "reflect.h2" }; -#line 4591 "reflect.h2" +#line 4623 "reflect.h2" // // Parse and generation context. // @@ -1836,33 +1844,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4611 "reflect.h2" +#line 4643 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4618 "reflect.h2" +#line 4650 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4630 "reflect.h2" +#line 4662 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4635 "reflect.h2" +#line 4667 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4639 "reflect.h2" +#line 4671 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4653 "reflect.h2" +#line 4685 "reflect.h2" }; -#line 4656 "reflect.h2" +#line 4688 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1875,25 +1883,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4674 "reflect.h2" +#line 4706 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4680 "reflect.h2" +#line 4712 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4687 "reflect.h2" +#line 4719 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4694 "reflect.h2" +#line 4726 "reflect.h2" }; -#line 4697 "reflect.h2" +#line 4729 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1909,7 +1917,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4713 "reflect.h2" +#line 4745 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1917,64 +1925,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4724 "reflect.h2" +#line 4756 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4737 "reflect.h2" +#line 4769 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4745 "reflect.h2" +#line 4777 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4749 "reflect.h2" +#line 4781 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4753 "reflect.h2" +#line 4785 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4765 "reflect.h2" +#line 4797 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4772 "reflect.h2" +#line 4804 "reflect.h2" public: auto next_alternative() & -> void; -#line 4778 "reflect.h2" +#line 4810 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4784 "reflect.h2" +#line 4816 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4788 "reflect.h2" +#line 4820 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4799 "reflect.h2" +#line 4831 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4803 "reflect.h2" +#line 4835 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4809 "reflect.h2" +#line 4841 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4813 "reflect.h2" +#line 4845 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4820 "reflect.h2" +#line 4852 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4831 "reflect.h2" +#line 4863 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1982,51 +1990,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4875 "reflect.h2" +#line 4907 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4887 "reflect.h2" +#line 4919 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4900 "reflect.h2" +#line 4932 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4923 "reflect.h2" +#line 4955 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4940 "reflect.h2" +#line 4972 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4961 "reflect.h2" +#line 4993 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 4971 "reflect.h2" +#line 5003 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 4975 "reflect.h2" +#line 5007 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5031 "reflect.h2" +#line 5063 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5070 "reflect.h2" +#line 5102 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5085 "reflect.h2" +#line 5117 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2038,10 +2046,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5096 "reflect.h2" +#line 5128 "reflect.h2" }; -#line 5099 "reflect.h2" +#line 5131 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2051,16 +2059,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5113 "reflect.h2" +#line 5145 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5116 "reflect.h2" +#line 5148 "reflect.h2" }; -#line 5119 "reflect.h2" +#line 5151 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2080,68 +2088,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5141 "reflect.h2" +#line 5173 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5147 "reflect.h2" +#line 5179 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5156 "reflect.h2" +#line 5188 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5167 "reflect.h2" +#line 5199 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5174 "reflect.h2" +#line 5206 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5194 "reflect.h2" +#line 5226 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5204 "reflect.h2" +#line 5236 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5227 "reflect.h2" +#line 5259 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5235 "reflect.h2" +#line 5267 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5239 "reflect.h2" +#line 5271 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5245 "reflect.h2" +#line 5277 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5251 "reflect.h2" +#line 5283 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5261 "reflect.h2" +#line 5293 "reflect.h2" public: auto finish_context() & -> void; -#line 5269 "reflect.h2" +#line 5301 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5275 "reflect.h2" +#line 5307 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5279 "reflect.h2" +#line 5311 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5283 "reflect.h2" +#line 5315 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5307 "reflect.h2" +#line 5339 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2149,7 +2157,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5313 "reflect.h2" +#line 5345 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2169,27 +2177,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5332 "reflect.h2" +#line 5364 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5338 "reflect.h2" +#line 5370 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5345 "reflect.h2" +#line 5377 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5362 "reflect.h2" +#line 5394 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5369 "reflect.h2" +#line 5401 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5382 "reflect.h2" +#line 5414 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2197,19 +2205,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5394 "reflect.h2" +#line 5426 "reflect.h2" }; -#line 5397 "reflect.h2" +#line 5429 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5403 "reflect.h2" +#line 5435 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5407 "reflect.h2" +#line 5439 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2217,7 +2225,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5412 "reflect.h2" +#line 5444 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2225,17 +2233,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5420 "reflect.h2" +#line 5452 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5431 "reflect.h2" +#line 5463 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5439 "reflect.h2" +#line 5471 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2243,7 +2251,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5442 "reflect.h2" +#line 5474 "reflect.h2" }; // Regex syntax: a @@ -2251,34 +2259,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5450 "reflect.h2" +#line 5482 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5459 "reflect.h2" +#line 5491 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5465 "reflect.h2" +#line 5497 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5469 "reflect.h2" +#line 5501 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5492 "reflect.h2" +#line 5524 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5513 "reflect.h2" +#line 5545 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5531 "reflect.h2" +#line 5563 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5546 "reflect.h2" +#line 5578 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5552 "reflect.h2" +#line 5584 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2286,33 +2294,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5556 "reflect.h2" +#line 5588 "reflect.h2" }; -#line 5559 "reflect.h2" +#line 5591 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5565 "reflect.h2" +#line 5597 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5577 "reflect.h2" +#line 5609 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5703 "reflect.h2" +#line 5735 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5712 "reflect.h2" +#line 5744 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5717 "reflect.h2" +#line 5749 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2320,20 +2328,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5724 "reflect.h2" +#line 5756 "reflect.h2" }; -#line 5727 "reflect.h2" +#line 5759 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5768 "reflect.h2" +#line 5800 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5779 "reflect.h2" +#line 5811 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2343,20 +2351,20 @@ class class_token class group_ref_token : public regex_token { -#line 5789 "reflect.h2" +#line 5821 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5801 "reflect.h2" +#line 5833 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5902 "reflect.h2" +#line 5934 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5906 "reflect.h2" +#line 5938 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2364,10 +2372,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5909 "reflect.h2" +#line 5941 "reflect.h2" }; -#line 5912 "reflect.h2" +#line 5944 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2381,29 +2389,29 @@ class group_ref_token class group_token : public regex_token { -#line 5926 "reflect.h2" +#line 5958 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5948 "reflect.h2" +#line 5980 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5962 "reflect.h2" +#line 5994 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6121 "reflect.h2" +#line 6153 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6129 "reflect.h2" +#line 6161 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6147 "reflect.h2" +#line 6179 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6178 "reflect.h2" +#line 6210 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2412,25 +2420,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6185 "reflect.h2" +#line 6217 "reflect.h2" }; -#line 6188 "reflect.h2" +#line 6220 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6229 "reflect.h2" +#line 6261 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6249 "reflect.h2" +#line 6281 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6265 "reflect.h2" +#line 6297 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2438,20 +2446,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6273 "reflect.h2" +#line 6305 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6282 "reflect.h2" +#line 6314 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6293 "reflect.h2" +#line 6325 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6300 "reflect.h2" +#line 6332 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2459,26 +2467,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6303 "reflect.h2" +#line 6335 "reflect.h2" }; -#line 6306 "reflect.h2" +#line 6338 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6334 "reflect.h2" +#line 6366 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6362 "reflect.h2" +#line 6394 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6368 "reflect.h2" +#line 6400 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2488,22 +2496,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6448 "reflect.h2" +#line 6480 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6460 "reflect.h2" +#line 6492 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6473 "reflect.h2" +#line 6505 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6492 "reflect.h2" +#line 6524 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6502 "reflect.h2" +#line 6534 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6513 "reflect.h2" +#line 6545 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2511,16 +2519,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6516 "reflect.h2" +#line 6548 "reflect.h2" }; -#line 6519 "reflect.h2" +#line 6551 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6525 "reflect.h2" +#line 6557 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2529,7 +2537,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6555 "reflect.h2" +#line 6587 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2538,14 +2546,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6577 "reflect.h2" +#line 6609 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6599 "reflect.h2" +#line 6631 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2566,24 +2574,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6622 "reflect.h2" +#line 6654 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6657 "reflect.h2" +#line 6689 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6671 "reflect.h2" +#line 6703 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6683 "reflect.h2" +#line 6715 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6738 "reflect.h2" +#line 6770 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2594,7 +2602,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6864 "reflect.h2" +#line 6896 "reflect.h2" } } @@ -6901,33 +6909,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // autodiff - stub // -#line 3724 "reflect.h2" +#line 3727 "reflect.h2" + // TODO: Extend + +#line 3730 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 3735 "reflect.h2" +#line 3741 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3737 "reflect.h2" +#line 3743 "reflect.h2" } -#line 3735 "reflect.h2" +#line 3741 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3737 "reflect.h2" +#line 3743 "reflect.h2" } -#line 3739 "reflect.h2" +#line 3745 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 3754 "reflect.h2" +#line 3760 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -6935,10 +6946,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_ } , declare_d{ declare_ }{ -#line 3759 "reflect.h2" +#line 3765 "reflect.h2" } -#line 3761 "reflect.h2" +#line 3767 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -6948,7 +6959,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 3770 "reflect.h2" +#line 3776 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -6987,62 +6998,78 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 3808 "reflect.h2" +#line 3814 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ + auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; + + if (pos == CPP2_UFCS(end)((*cpp2::impl::assert_not_null(ctx)).math_funcs)) { + return false; + } + + auto func_diff {string_util::replace_all((*cpp2::impl::assert_not_null(cpp2::move(pos))).second, "_x_", arg)}; + + diff += "" + cpp2::to_string(lhs) + "_d = " + cpp2::to_string(cpp2::move(func_diff)) + " * " + cpp2::to_string(arg) + "_d;\n"; + diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(func_name) + "(" + cpp2::to_string(arg) + ");\n"; + + return true; + } + +#line 3829 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 3812 "reflect.h2" +#line 3833 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 3816 "reflect.h2" +#line 3837 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 3820 "reflect.h2" +#line 3841 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 3824 "reflect.h2" +#line 3845 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 3828 "reflect.h2" +#line 3849 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 3832 "reflect.h2" +#line 3853 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 3836 "reflect.h2" +#line 3857 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 3840 "reflect.h2" +#line 3861 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 3844 "reflect.h2" +#line 3865 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 3848 "reflect.h2" +#line 3869 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 3852 "reflect.h2" +#line 3873 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7069,7 +7096,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 3878 "reflect.h2" +#line 3899 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7096,7 +7123,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 3905 "reflect.h2" +#line 3926 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; @@ -7114,18 +7141,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3922 "reflect.h2" +#line 3943 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 3926 "reflect.h2" +#line 3947 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); } -#line 3931 "reflect.h2" +#line 3952 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7136,6 +7163,9 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return ; } + auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; + auto func_name {CPP2_UFCS(to_string)(cpp2::move(primary))}; + // First handle all arguments auto term {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(terms), 0)}; std::vector args {}; @@ -7146,9 +7176,15 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(push_back)(args, handle_expression_term(CPP2_UFCS(get_expression)(cpp2::move(term)))); } + // Check if this is a special function, with a user defined handling. + // TODO: Extend to a generalized version and not only functions with one argument. + if (handle_math_func(func_name, CPP2_ASSERT_IN_BOUNDS_LITERAL(args, 0))) { + return ; + } + // All arguments have now been handled. Form the function call auto ret_temp {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - diff += "" + cpp2::to_string(ret_temp) + " := " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))) + "_diff("; + diff += "" + cpp2::to_string(ret_temp) + " := " + cpp2::to_string(cpp2::move(func_name)) + "_diff("; for ( auto const& arg : cpp2::move(args) ) { diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; } @@ -7158,16 +7194,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // TODO: Look up return value name of function. diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(ret_temp) + ".r;\n"; diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(cpp2::move(ret_temp)) + ".r_d;\n"; + + // TODO: Add function to list of functions/objects for differentiation. } -#line 3969 "reflect.h2" +#line 4001 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) : autodiff_handler_base{ ctx_ }{ -#line 3971 "reflect.h2" +#line 4003 "reflect.h2" } -#line 3973 "reflect.h2" +#line 4005 "reflect.h2" auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7197,7 +7235,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4003 "reflect.h2" +#line 4035 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7237,7 +7275,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 4043 "reflect.h2" +#line 4075 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -7344,7 +7382,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4059 "reflect.h2" +#line 4091 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -7709,7 +7747,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4424 "reflect.h2" +#line 4456 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -7725,11 +7763,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4440 "reflect.h2" +#line 4472 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4444 "reflect.h2" +#line 4476 "reflect.h2" // mod: i // mod: m // mod: s @@ -7737,116 +7775,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4453 "reflect.h2" +#line 4485 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4462 "reflect.h2" +#line 4494 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4464 "reflect.h2" +#line 4496 "reflect.h2" } -#line 4466 "reflect.h2" +#line 4498 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4468 "reflect.h2" +#line 4500 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4474 "reflect.h2" +#line 4506 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4475 "reflect.h2" +#line 4507 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4476 "reflect.h2" +#line 4508 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4491 "reflect.h2" +#line 4523 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4494 "reflect.h2" +#line 4526 "reflect.h2" } -#line 4496 "reflect.h2" +#line 4528 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4500 "reflect.h2" +#line 4532 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4512 "reflect.h2" +#line 4544 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4515 "reflect.h2" +#line 4547 "reflect.h2" } -#line 4517 "reflect.h2" +#line 4549 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4521 "reflect.h2" +#line 4553 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4531 "reflect.h2" +#line 4563 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4533 "reflect.h2" +#line 4565 "reflect.h2" } -#line 4535 "reflect.h2" +#line 4567 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4539 "reflect.h2" +#line 4571 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4551 "reflect.h2" +#line 4583 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4554 "reflect.h2" +#line 4586 "reflect.h2" } -#line 4556 "reflect.h2" +#line 4588 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4562 "reflect.h2" +#line 4594 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4568 "reflect.h2" +#line 4600 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7855,7 +7893,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4576 "reflect.h2" +#line 4608 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7871,7 +7909,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4604 "reflect.h2" +#line 4636 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7879,14 +7917,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4612 "reflect.h2" +#line 4644 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4619 "reflect.h2" +#line 4651 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7898,15 +7936,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4631 "reflect.h2" +#line 4663 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4636 "reflect.h2" +#line 4668 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4640 "reflect.h2" +#line 4672 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7927,7 +7965,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4666 "reflect.h2" +#line 4698 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7936,20 +7974,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4675 "reflect.h2" +#line 4707 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4681 "reflect.h2" +#line 4713 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4688 "reflect.h2" +#line 4720 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -7964,16 +8002,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4718 "reflect.h2" +#line 4750 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4722 "reflect.h2" +#line 4754 "reflect.h2" } -#line 4728 "reflect.h2" +#line 4760 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -7983,7 +8021,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4738 "reflect.h2" +#line 4770 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -7991,17 +8029,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4745 "reflect.h2" +#line 4777 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4749 "reflect.h2" +#line 4781 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4756 "reflect.h2" +#line 4788 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8011,7 +8049,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4765 "reflect.h2" +#line 4797 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8019,24 +8057,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4772 "reflect.h2" +#line 4804 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4780 "reflect.h2" +#line 4812 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4784 "reflect.h2" +#line 4816 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4788 "reflect.h2" +#line 4820 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8048,22 +8086,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4799 "reflect.h2" +#line 4831 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4805 "reflect.h2" +#line 4837 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4809 "reflect.h2" +#line 4841 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4813 "reflect.h2" +#line 4845 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8071,7 +8109,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4820 "reflect.h2" +#line 4852 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8083,10 +8121,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4833 "reflect.h2" +#line 4865 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4836 "reflect.h2" +#line 4868 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8126,7 +8164,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4876 "reflect.h2" +#line 4908 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8138,14 +8176,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4887 "reflect.h2" +#line 4919 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4888 "reflect.h2" +#line 4920 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4889 "reflect.h2" +#line 4921 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4891 "reflect.h2" +#line 4923 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8155,10 +8193,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4900 "reflect.h2" +#line 4932 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4902 "reflect.h2" +#line 4934 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8180,14 +8218,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4923 "reflect.h2" +#line 4955 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4924 "reflect.h2" +#line 4956 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4925 "reflect.h2" +#line 4957 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4927 "reflect.h2" +#line 4959 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8201,7 +8239,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4940 "reflect.h2" +#line 4972 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8223,7 +8261,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4961 "reflect.h2" +#line 4993 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8234,12 +8272,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4971 "reflect.h2" +#line 5003 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 4972 "reflect.h2" +#line 5004 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 4977 "reflect.h2" +#line 5009 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8294,7 +8332,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5031 "reflect.h2" +#line 5063 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8334,7 +8372,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5070 "reflect.h2" +#line 5102 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8350,21 +8388,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5087 "reflect.h2" +#line 5119 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5088 "reflect.h2" +#line 5120 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5089 "reflect.h2" +#line 5121 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5091 "reflect.h2" +#line 5123 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5106 "reflect.h2" +#line 5138 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8372,7 +8410,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5113 "reflect.h2" +#line 5145 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8382,22 +8420,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5131 "reflect.h2" +#line 5163 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5136 "reflect.h2" +#line 5168 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5142 "reflect.h2" +#line 5174 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5148 "reflect.h2" +#line 5180 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8406,7 +8444,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5156 "reflect.h2" +#line 5188 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8418,7 +8456,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5167 "reflect.h2" +#line 5199 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8426,7 +8464,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5174 "reflect.h2" +#line 5206 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8447,7 +8485,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5195 "reflect.h2" +#line 5227 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8457,7 +8495,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5205 "reflect.h2" +#line 5237 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8480,33 +8518,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5229 "reflect.h2" +#line 5261 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5235 "reflect.h2" +#line 5267 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5239 "reflect.h2" +#line 5271 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5245 "reflect.h2" +#line 5277 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5253 "reflect.h2" +#line 5285 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8515,7 +8553,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5261 "reflect.h2" +#line 5293 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8524,22 +8562,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5271 "reflect.h2" +#line 5303 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5275 "reflect.h2" +#line 5307 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5279 "reflect.h2" +#line 5311 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5283 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8563,18 +8601,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5308 "reflect.h2" +#line 5340 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5323 "reflect.h2" +#line 5355 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5325 "reflect.h2" +#line 5357 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8585,15 +8623,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5340 "reflect.h2" +#line 5372 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5343 "reflect.h2" +#line 5375 "reflect.h2" } -#line 5345 "reflect.h2" +#line 5377 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8611,7 +8649,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5362 "reflect.h2" +#line 5394 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8619,7 +8657,7 @@ generation_function_context::generation_function_context(){} } } -#line 5369 "reflect.h2" +#line 5401 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8633,7 +8671,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5382 "reflect.h2" +#line 5414 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8649,14 +8687,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5403 "reflect.h2" +#line 5435 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5405 "reflect.h2" +#line 5437 "reflect.h2" } -#line 5407 "reflect.h2" +#line 5439 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8665,11 +8703,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5422 "reflect.h2" +#line 5454 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5424 "reflect.h2" +#line 5456 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8677,7 +8715,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5431 "reflect.h2" +#line 5463 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8686,37 +8724,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5439 "reflect.h2" +#line 5471 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5453 "reflect.h2" +#line 5485 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5457 "reflect.h2" +#line 5489 "reflect.h2" } -#line 5459 "reflect.h2" +#line 5491 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5463 "reflect.h2" +#line 5495 "reflect.h2" } -#line 5465 "reflect.h2" +#line 5497 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5469 "reflect.h2" +#line 5501 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -8725,14 +8763,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5475 "reflect.h2" +#line 5507 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5480 "reflect.h2" +#line 5512 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8745,7 +8783,7 @@ size_t i{0}; } } -#line 5492 "reflect.h2" +#line 5524 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8767,7 +8805,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5513 "reflect.h2" +#line 5545 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8786,7 +8824,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5531 "reflect.h2" +#line 5563 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8802,14 +8840,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5546 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5552 "reflect.h2" +#line 5584 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8817,19 +8855,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5569 "reflect.h2" +#line 5601 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5570 "reflect.h2" +#line 5602 "reflect.h2" { -#line 5575 "reflect.h2" +#line 5607 "reflect.h2" } -#line 5578 "reflect.h2" +#line 5610 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8955,7 +8993,7 @@ size_t i{0}; ); } -#line 5703 "reflect.h2" +#line 5735 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -8965,13 +9003,13 @@ size_t i{0}; ); } -#line 5712 "reflect.h2" +#line 5744 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5717 "reflect.h2" +#line 5749 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -8982,12 +9020,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5729 "reflect.h2" +#line 5761 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5734 "reflect.h2" +#line 5766 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9021,7 +9059,7 @@ size_t i{0}; } -#line 5770 "reflect.h2" +#line 5802 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9030,19 +9068,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5793 "reflect.h2" +#line 5825 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5794 "reflect.h2" +#line 5826 "reflect.h2" { -#line 5799 "reflect.h2" +#line 5831 "reflect.h2" } -#line 5801 "reflect.h2" +#line 5833 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9144,19 +9182,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5902 "reflect.h2" +#line 5934 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5906 "reflect.h2" +#line 5938 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5930 "reflect.h2" +#line 5962 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9175,7 +9213,7 @@ size_t i{0}; return r; } -#line 5948 "reflect.h2" +#line 5980 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9190,7 +9228,7 @@ size_t i{0}; return r; } -#line 5962 "reflect.h2" +#line 5994 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9350,7 +9388,7 @@ size_t i{0}; } } -#line 6121 "reflect.h2" +#line 6153 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9359,7 +9397,7 @@ size_t i{0}; return r; } -#line 6129 "reflect.h2" +#line 6161 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9378,7 +9416,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6147 "reflect.h2" +#line 6179 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9410,7 +9448,7 @@ size_t i{0}; } } -#line 6178 "reflect.h2" +#line 6210 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9421,7 +9459,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6190 "reflect.h2" +#line 6222 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9460,7 +9498,7 @@ size_t i{0}; return r; } -#line 6231 "reflect.h2" +#line 6263 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9478,7 +9516,7 @@ size_t i{0}; }} } -#line 6251 "reflect.h2" +#line 6283 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9492,16 +9530,16 @@ size_t i{0}; } } -#line 6277 "reflect.h2" +#line 6309 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6280 "reflect.h2" +#line 6312 "reflect.h2" } -#line 6282 "reflect.h2" +#line 6314 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9513,7 +9551,7 @@ size_t i{0}; } } -#line 6293 "reflect.h2" +#line 6325 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9521,14 +9559,14 @@ size_t i{0}; return r; } -#line 6300 "reflect.h2" +#line 6332 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6308 "reflect.h2" +#line 6340 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9554,7 +9592,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6336 "reflect.h2" +#line 6368 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9580,11 +9618,11 @@ size_t i{0}; return r; } -#line 6373 "reflect.h2" +#line 6405 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6375 "reflect.h2" +#line 6407 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9658,7 +9696,7 @@ size_t i{0}; return nullptr; } -#line 6448 "reflect.h2" +#line 6480 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9671,7 +9709,7 @@ size_t i{0}; }} } -#line 6460 "reflect.h2" +#line 6492 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9685,7 +9723,7 @@ size_t i{0}; }} } -#line 6473 "reflect.h2" +#line 6505 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9705,7 +9743,7 @@ size_t i{0}; return r; } -#line 6492 "reflect.h2" +#line 6524 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -9716,7 +9754,7 @@ size_t i{0}; return r; } -#line 6502 "reflect.h2" +#line 6534 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9728,14 +9766,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6513 "reflect.h2" +#line 6545 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6525 "reflect.h2" +#line 6557 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9759,7 +9797,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6549 "reflect.h2" +#line 6581 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9769,7 +9807,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6561 "reflect.h2" +#line 6593 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9785,7 +9823,7 @@ size_t i{0}; } } -#line 6581 "reflect.h2" +#line 6613 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9803,15 +9841,15 @@ size_t i{0}; }} } -#line 6617 "reflect.h2" +#line 6649 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6620 "reflect.h2" +#line 6652 "reflect.h2" } -#line 6622 "reflect.h2" +#line 6654 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9847,7 +9885,7 @@ size_t i{0}; return source; } -#line 6657 "reflect.h2" +#line 6689 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9863,7 +9901,7 @@ size_t i{0}; } } -#line 6673 "reflect.h2" +#line 6705 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9872,7 +9910,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9927,7 +9965,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6742 "reflect.h2" +#line 6774 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10049,7 +10087,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6864 "reflect.h2" +#line 6896 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index c780463d5..8b80d565f 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3720,6 +3720,12 @@ sample_traverser: (idexpr: meta::id_expression, indent: i32) = autodiff_context: type = { private temporary_count : int = 0; + public math_funcs : std::map = ( + std::make_pair("sin", "cos(_x_)"), + std::make_pair("cos", "-sin(_x_)"), + std::make_pair("exp", "exp(_x_)"), + // TODO: Extend + ); gen_temporary : (inout this) -> std::string = { temporary_count += 1; @@ -3805,6 +3811,21 @@ autodiff_expression_handler: type = { } } + handle_math_func :(inout this, func_name: std::string, arg: std::string) -> bool = { + pos := ctx*.math_funcs.find(func_name); + + if pos == ctx*.math_funcs.end() { + return false; + } + + func_diff := string_util::replace_all(pos*.second, "_x_", arg); + + diff += "(lhs)$_d = (func_diff)$ * (arg)$_d;\n"; + diff += "(lhs)$ = (func_name)$((arg)$);\n"; + + return true; + } + traverse: (override inout this, expr: meta::expression) = { base::traverse(expr); } @@ -3938,6 +3959,9 @@ autodiff_expression_handler: type = { return; } + primary := postfix.get_primary_expression(); + func_name := primary.to_string(); + // First handle all arguments term := terms[0]; args : std::vector = (); @@ -3948,9 +3972,15 @@ autodiff_expression_handler: type = { args.push_back(handle_expression_term(term.get_expression())); } + // Check if this is a special function, with a user defined handling. + // TODO: Extend to a generalized version and not only functions with one argument. + if handle_math_func(func_name, args[0]) { + return; + } + // All arguments have now been handled. Form the function call ret_temp := ctx*.gen_temporary(); - diff += "(ret_temp)$ := (postfix.get_primary_expression().to_string())$_diff("; + diff += "(ret_temp)$ := (func_name)$_diff("; for args do (arg) { diff += "(arg)$, (arg)$_d,"; } @@ -3960,6 +3990,8 @@ autodiff_expression_handler: type = { // TODO: Look up return value name of function. diff += "(lhs)$ (declare_p)$= (ret_temp)$.r;\n"; diff += "(lhs)$_d (declare_d)$= (ret_temp)$.r_d;\n"; + + // TODO: Add function to list of functions/objects for differentiation. } } From 8166f0f2f80c960294dc9ca0a86dcfe6d1398ae1 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 10:11:31 +0200 Subject: [PATCH 09/54] Added declarations and statements to simple_traversal. --- source/reflect.h | 1486 ++++++++++++++++++++++++++------------------- source/reflect.h2 | 185 ++++++ 2 files changed, 1056 insertions(+), 615 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 93f9bb402..fa430a8aa 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -102,93 +102,93 @@ class value_member_info; #line 2436 "reflect.h2" class simple_traverser; -#line 3721 "reflect.h2" +#line 3906 "reflect.h2" class autodiff_context; -#line 3736 "reflect.h2" +#line 3921 "reflect.h2" class autodiff_handler_base; -#line 3750 "reflect.h2" +#line 3935 "reflect.h2" class autodiff_expression_handler; -#line 3998 "reflect.h2" +#line 4183 "reflect.h2" class autodiff_stmt_handler; -#line 4474 "reflect.h2" +#line 4659 "reflect.h2" class expression_flags; -#line 4490 "reflect.h2" +#line 4675 "reflect.h2" class regex_token; -#line 4517 "reflect.h2" +#line 4702 "reflect.h2" class regex_token_check; -#line 4538 "reflect.h2" +#line 4723 "reflect.h2" class regex_token_code; -#line 4559 "reflect.h2" +#line 4744 "reflect.h2" class regex_token_empty; -#line 4577 "reflect.h2" +#line 4762 "reflect.h2" class regex_token_list; -#line 4629 "reflect.h2" +#line 4814 "reflect.h2" class parse_context_group_state; -#line 4690 "reflect.h2" +#line 4875 "reflect.h2" class parse_context_branch_reset_state; -#line 4733 "reflect.h2" +#line 4918 "reflect.h2" class parse_context; -#line 5134 "reflect.h2" +#line 5319 "reflect.h2" class generation_function_context; -#line 5152 "reflect.h2" +#line 5337 "reflect.h2" class generation_context; -#line 5351 "reflect.h2" +#line 5536 "reflect.h2" class alternative_token; -#line 5366 "reflect.h2" +#line 5551 "reflect.h2" class alternative_token_gen; -#line 5431 "reflect.h2" +#line 5616 "reflect.h2" class any_token; -#line 5448 "reflect.h2" +#line 5633 "reflect.h2" class atomic_group_token; -#line 5478 "reflect.h2" +#line 5663 "reflect.h2" class char_token; -#line 5593 "reflect.h2" +#line 5778 "reflect.h2" class class_token; -#line 5817 "reflect.h2" +#line 6002 "reflect.h2" class group_ref_token; -#line 5954 "reflect.h2" +#line 6139 "reflect.h2" class group_token; -#line 6301 "reflect.h2" +#line 6486 "reflect.h2" class lookahead_lookbehind_token; -#line 6396 "reflect.h2" +#line 6581 "reflect.h2" class range_token; -#line 6553 "reflect.h2" +#line 6738 "reflect.h2" class special_range_token; -#line 6639 "reflect.h2" +#line 6824 "reflect.h2" template class regex_generator; -#line 6896 "reflect.h2" +#line 7081 "reflect.h2" } } @@ -1319,220 +1319,280 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in #line 2436 "reflect.h2" class simple_traverser { + public: virtual auto pre_traverse(cpp2::impl::in decl) -> void; + +#line 2442 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in decl) -> void; + +#line 2462 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in f) -> void; + +#line 2466 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in f) -> void; + +#line 2487 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in o) -> void; + +#line 2491 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in o) -> void; + +#line 2499 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in t) -> void; + +#line 2503 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in t) -> void; + +#line 2511 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in t) -> void; + +#line 2515 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in t) -> void; + +#line 2520 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; + +#line 2524 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in stmt) -> void; + +#line 2559 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; + +#line 2563 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in stmt) -> void; + +#line 2573 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; + +#line 2577 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in stmt) -> void; + +#line 2585 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; + +#line 2589 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in stmt) -> void; + +#line 2608 "reflect.h2" + public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; + +#line 2612 "reflect.h2" + public: virtual auto traverse(cpp2::impl::in stmt) -> void; + +#line 2623 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in expr) -> void; -#line 2444 "reflect.h2" +#line 2629 "reflect.h2" public: virtual auto traverse(cpp2::impl::in expr) -> void; -#line 2458 "reflect.h2" +#line 2643 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2475 "reflect.h2" +#line 2660 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2486 "reflect.h2" +#line 2671 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2503 "reflect.h2" +#line 2688 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2515 "reflect.h2" +#line 2700 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2532 "reflect.h2" +#line 2717 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2543 "reflect.h2" +#line 2728 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2560 "reflect.h2" +#line 2745 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2571 "reflect.h2" +#line 2756 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2588 "reflect.h2" +#line 2773 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2600 "reflect.h2" +#line 2785 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2617 "reflect.h2" +#line 2802 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2629 "reflect.h2" +#line 2814 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2646 "reflect.h2" +#line 2831 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2657 "reflect.h2" +#line 2842 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2674 "reflect.h2" +#line 2859 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2685 "reflect.h2" +#line 2870 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2702 "reflect.h2" +#line 2887 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2713 "reflect.h2" +#line 2898 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2730 "reflect.h2" +#line 2915 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2741 "reflect.h2" +#line 2926 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2758 "reflect.h2" +#line 2943 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2770 "reflect.h2" +#line 2955 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2787 "reflect.h2" +#line 2972 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2798 "reflect.h2" +#line 2983 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in isas) -> void; -#line 2814 "reflect.h2" +#line 2999 "reflect.h2" public: virtual auto traverse(cpp2::impl::in isas) -> void; -#line 2825 "reflect.h2" +#line 3010 "reflect.h2" public: virtual auto traverse(cpp2::impl::in exprs) -> void; -#line 2832 "reflect.h2" +#line 3017 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in prefix) -> void; -#line 2848 "reflect.h2" +#line 3033 "reflect.h2" public: virtual auto traverse(cpp2::impl::in prefix) -> void; -#line 2853 "reflect.h2" +#line 3038 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in postfix) -> void; -#line 2869 "reflect.h2" +#line 3054 "reflect.h2" public: virtual auto traverse(cpp2::impl::in postfix) -> void; -#line 2888 "reflect.h2" +#line 3073 "reflect.h2" public: virtual auto traverse(cpp2::impl::in uid) -> void; -#line 2894 "reflect.h2" +#line 3079 "reflect.h2" public: virtual auto traverse(cpp2::impl::in qid) -> void; -#line 2904 "reflect.h2" +#line 3089 "reflect.h2" public: virtual auto traverse(cpp2::impl::in tid) -> void; -#line 2921 "reflect.h2" +#line 3106 "reflect.h2" public: virtual auto traverse(cpp2::impl::in primary) -> void; -#line 2941 "reflect.h2" +#line 3126 "reflect.h2" public: virtual auto traverse(cpp2::impl::in idexpr) -> void; public: simple_traverser() = default; public: simple_traverser(simple_traverser const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(simple_traverser const&) -> void = delete; -#line 2956 "reflect.h2" +#line 3141 "reflect.h2" }; -#line 2969 "reflect.h2" +#line 3154 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; -#line 2991 "reflect.h2" +#line 3176 "reflect.h2" auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent = 0) -> void; -#line 3021 "reflect.h2" +#line 3206 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void; -#line 3031 "reflect.h2" +#line 3216 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3041 "reflect.h2" +#line 3226 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3060 "reflect.h2" +#line 3245 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3107 "reflect.h2" +#line 3292 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3124 "reflect.h2" +#line 3309 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3134 "reflect.h2" +#line 3319 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3166 "reflect.h2" +#line 3351 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void; -#line 3177 "reflect.h2" +#line 3362 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3207 "reflect.h2" +#line 3392 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3237 "reflect.h2" +#line 3422 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3267 "reflect.h2" +#line 3452 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3297 "reflect.h2" +#line 3482 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3327 "reflect.h2" +#line 3512 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3357 "reflect.h2" +#line 3542 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3387 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3417 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3447 "reflect.h2" +#line 3632 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3477 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3507 "reflect.h2" +#line 3692 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3537 "reflect.h2" +#line 3722 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void; -#line 3563 "reflect.h2" +#line 3748 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void; -#line 3578 "reflect.h2" +#line 3763 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void; -#line 3602 "reflect.h2" +#line 3787 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void; -#line 3635 "reflect.h2" +#line 3820 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void; -#line 3646 "reflect.h2" +#line 3831 "reflect.h2" auto sample_traverser(cpp2::impl::in qid, cpp2::impl::in indent) -> void; -#line 3662 "reflect.h2" +#line 3847 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void; -#line 3679 "reflect.h2" +#line 3864 "reflect.h2" auto sample_traverser(cpp2::impl::in primary, cpp2::impl::in indent) -> void; -#line 3699 "reflect.h2" +#line 3884 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; -#line 3721 "reflect.h2" +#line 3906 "reflect.h2" class autodiff_context { private: int temporary_count {0}; public: std::map math_funcs { @@ -1540,14 +1600,14 @@ class autodiff_context { std::make_pair("cos", "-sin(_x_)"), std::make_pair("exp", "exp(_x_)")}; -#line 3730 "reflect.h2" +#line 3915 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3734 "reflect.h2" +#line 3919 "reflect.h2" }; class autodiff_handler_base { @@ -1556,21 +1616,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3741 "reflect.h2" +#line 3926 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3745 "reflect.h2" +#line 3930 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3748 "reflect.h2" +#line 3933 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3754 "reflect.h2" +#line 3939 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1579,89 +1639,89 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3767 "reflect.h2" +#line 3952 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 3776 "reflect.h2" +#line 3961 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3814 "reflect.h2" +#line 3999 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 3829 "reflect.h2" +#line 4014 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 3833 "reflect.h2" +#line 4018 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3837 "reflect.h2" +#line 4022 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3841 "reflect.h2" +#line 4026 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3845 "reflect.h2" +#line 4030 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3849 "reflect.h2" +#line 4034 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3853 "reflect.h2" +#line 4038 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3857 "reflect.h2" +#line 4042 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3861 "reflect.h2" +#line 4046 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3865 "reflect.h2" +#line 4050 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3869 "reflect.h2" +#line 4054 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3873 "reflect.h2" +#line 4058 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3899 "reflect.h2" +#line 4084 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 3943 "reflect.h2" +#line 4128 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 3947 "reflect.h2" +#line 4132 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 3952 "reflect.h2" +#line 4137 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 3996 "reflect.h2" +#line 4181 "reflect.h2" }; class autodiff_stmt_handler: public autodiff_handler_base { -#line 4001 "reflect.h2" +#line 4186 "reflect.h2" public: autodiff_stmt_handler(autodiff_context* ctx_); -#line 4005 "reflect.h2" +#line 4190 "reflect.h2" public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4033 "reflect.h2" +#line 4218 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4470 "reflect.h2" +#line 4655 "reflect.h2" using error_func = std::function x)>; -#line 4474 "reflect.h2" +#line 4659 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1696,20 +1756,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4482 "reflect.h2" +#line 4667 "reflect.h2" }; -#line 4490 "reflect.h2" +#line 4675 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4498 "reflect.h2" +#line 4683 "reflect.h2" public: explicit regex_token(); -#line 4503 "reflect.h2" +#line 4688 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1721,103 +1781,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4509 "reflect.h2" +#line 4694 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4515 "reflect.h2" +#line 4700 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4521 "reflect.h2" +#line 4706 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4528 "reflect.h2" +#line 4713 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4532 "reflect.h2" +#line 4717 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4533 "reflect.h2" +#line 4718 "reflect.h2" }; -#line 4536 "reflect.h2" +#line 4721 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4542 "reflect.h2" +#line 4727 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4549 "reflect.h2" +#line 4734 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4553 "reflect.h2" +#line 4738 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4554 "reflect.h2" +#line 4739 "reflect.h2" }; -#line 4557 "reflect.h2" +#line 4742 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4563 "reflect.h2" +#line 4748 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4567 "reflect.h2" +#line 4752 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4571 "reflect.h2" +#line 4756 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4572 "reflect.h2" +#line 4757 "reflect.h2" }; -#line 4575 "reflect.h2" +#line 4760 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4581 "reflect.h2" +#line 4766 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4588 "reflect.h2" +#line 4773 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4594 "reflect.h2" +#line 4779 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4600 "reflect.h2" +#line 4785 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4608 "reflect.h2" +#line 4793 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1825,10 +1885,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4620 "reflect.h2" +#line 4805 "reflect.h2" }; -#line 4623 "reflect.h2" +#line 4808 "reflect.h2" // // Parse and generation context. // @@ -1844,33 +1904,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4643 "reflect.h2" +#line 4828 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4650 "reflect.h2" +#line 4835 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4662 "reflect.h2" +#line 4847 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4667 "reflect.h2" +#line 4852 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4671 "reflect.h2" +#line 4856 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4685 "reflect.h2" +#line 4870 "reflect.h2" }; -#line 4688 "reflect.h2" +#line 4873 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1883,25 +1943,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4706 "reflect.h2" +#line 4891 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4712 "reflect.h2" +#line 4897 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4719 "reflect.h2" +#line 4904 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4726 "reflect.h2" +#line 4911 "reflect.h2" }; -#line 4729 "reflect.h2" +#line 4914 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1917,7 +1977,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4745 "reflect.h2" +#line 4930 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1925,64 +1985,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4756 "reflect.h2" +#line 4941 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4769 "reflect.h2" +#line 4954 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4777 "reflect.h2" +#line 4962 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4781 "reflect.h2" +#line 4966 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4785 "reflect.h2" +#line 4970 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4797 "reflect.h2" +#line 4982 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4804 "reflect.h2" +#line 4989 "reflect.h2" public: auto next_alternative() & -> void; -#line 4810 "reflect.h2" +#line 4995 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 4816 "reflect.h2" +#line 5001 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 4820 "reflect.h2" +#line 5005 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 4831 "reflect.h2" +#line 5016 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4835 "reflect.h2" +#line 5020 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 4841 "reflect.h2" +#line 5026 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 4845 "reflect.h2" +#line 5030 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 4852 "reflect.h2" +#line 5037 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 4863 "reflect.h2" +#line 5048 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -1990,51 +2050,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 4907 "reflect.h2" +#line 5092 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 4919 "reflect.h2" +#line 5104 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 4932 "reflect.h2" +#line 5117 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 4955 "reflect.h2" +#line 5140 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 4972 "reflect.h2" +#line 5157 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 4993 "reflect.h2" +#line 5178 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5003 "reflect.h2" +#line 5188 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5007 "reflect.h2" +#line 5192 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5063 "reflect.h2" +#line 5248 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5102 "reflect.h2" +#line 5287 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5117 "reflect.h2" +#line 5302 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2046,10 +2106,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5128 "reflect.h2" +#line 5313 "reflect.h2" }; -#line 5131 "reflect.h2" +#line 5316 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2059,16 +2119,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5145 "reflect.h2" +#line 5330 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5148 "reflect.h2" +#line 5333 "reflect.h2" }; -#line 5151 "reflect.h2" +#line 5336 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2088,68 +2148,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5173 "reflect.h2" +#line 5358 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5179 "reflect.h2" +#line 5364 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5188 "reflect.h2" +#line 5373 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5199 "reflect.h2" +#line 5384 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5206 "reflect.h2" +#line 5391 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5226 "reflect.h2" +#line 5411 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5236 "reflect.h2" +#line 5421 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5259 "reflect.h2" +#line 5444 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5267 "reflect.h2" +#line 5452 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5271 "reflect.h2" +#line 5456 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5277 "reflect.h2" +#line 5462 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5283 "reflect.h2" +#line 5468 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5293 "reflect.h2" +#line 5478 "reflect.h2" public: auto finish_context() & -> void; -#line 5301 "reflect.h2" +#line 5486 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5307 "reflect.h2" +#line 5492 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5311 "reflect.h2" +#line 5496 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5315 "reflect.h2" +#line 5500 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5339 "reflect.h2" +#line 5524 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2157,7 +2217,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5345 "reflect.h2" +#line 5530 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2177,27 +2237,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5364 "reflect.h2" +#line 5549 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5370 "reflect.h2" +#line 5555 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5377 "reflect.h2" +#line 5562 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5394 "reflect.h2" +#line 5579 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5401 "reflect.h2" +#line 5586 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5414 "reflect.h2" +#line 5599 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2205,19 +2265,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5426 "reflect.h2" +#line 5611 "reflect.h2" }; -#line 5429 "reflect.h2" +#line 5614 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5435 "reflect.h2" +#line 5620 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5439 "reflect.h2" +#line 5624 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2225,7 +2285,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5444 "reflect.h2" +#line 5629 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2233,17 +2293,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5452 "reflect.h2" +#line 5637 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5463 "reflect.h2" +#line 5648 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5471 "reflect.h2" +#line 5656 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2251,7 +2311,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5474 "reflect.h2" +#line 5659 "reflect.h2" }; // Regex syntax: a @@ -2259,34 +2319,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5482 "reflect.h2" +#line 5667 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5491 "reflect.h2" +#line 5676 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5497 "reflect.h2" +#line 5682 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5501 "reflect.h2" +#line 5686 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5524 "reflect.h2" +#line 5709 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5545 "reflect.h2" +#line 5730 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5563 "reflect.h2" +#line 5748 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5578 "reflect.h2" +#line 5763 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5584 "reflect.h2" +#line 5769 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2294,33 +2354,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5588 "reflect.h2" +#line 5773 "reflect.h2" }; -#line 5591 "reflect.h2" +#line 5776 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5597 "reflect.h2" +#line 5782 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5609 "reflect.h2" +#line 5794 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5735 "reflect.h2" +#line 5920 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5744 "reflect.h2" +#line 5929 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5749 "reflect.h2" +#line 5934 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2328,20 +2388,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5756 "reflect.h2" +#line 5941 "reflect.h2" }; -#line 5759 "reflect.h2" +#line 5944 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5800 "reflect.h2" +#line 5985 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5811 "reflect.h2" +#line 5996 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2351,20 +2411,20 @@ class class_token class group_ref_token : public regex_token { -#line 5821 "reflect.h2" +#line 6006 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 5833 "reflect.h2" +#line 6018 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5934 "reflect.h2" +#line 6119 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5938 "reflect.h2" +#line 6123 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2372,10 +2432,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 5941 "reflect.h2" +#line 6126 "reflect.h2" }; -#line 5944 "reflect.h2" +#line 6129 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2389,29 +2449,29 @@ class group_ref_token class group_token : public regex_token { -#line 5958 "reflect.h2" +#line 6143 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 5980 "reflect.h2" +#line 6165 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 5994 "reflect.h2" +#line 6179 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6153 "reflect.h2" +#line 6338 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6161 "reflect.h2" +#line 6346 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6179 "reflect.h2" +#line 6364 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6210 "reflect.h2" +#line 6395 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2420,25 +2480,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6217 "reflect.h2" +#line 6402 "reflect.h2" }; -#line 6220 "reflect.h2" +#line 6405 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6261 "reflect.h2" +#line 6446 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6281 "reflect.h2" +#line 6466 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6297 "reflect.h2" +#line 6482 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2446,20 +2506,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6305 "reflect.h2" +#line 6490 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6314 "reflect.h2" +#line 6499 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6325 "reflect.h2" +#line 6510 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6332 "reflect.h2" +#line 6517 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2467,26 +2527,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6335 "reflect.h2" +#line 6520 "reflect.h2" }; -#line 6338 "reflect.h2" +#line 6523 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6366 "reflect.h2" +#line 6551 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6394 "reflect.h2" +#line 6579 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6400 "reflect.h2" +#line 6585 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2496,22 +2556,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6480 "reflect.h2" +#line 6665 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6492 "reflect.h2" +#line 6677 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6505 "reflect.h2" +#line 6690 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6524 "reflect.h2" +#line 6709 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6534 "reflect.h2" +#line 6719 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6545 "reflect.h2" +#line 6730 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2519,16 +2579,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6548 "reflect.h2" +#line 6733 "reflect.h2" }; -#line 6551 "reflect.h2" +#line 6736 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6557 "reflect.h2" +#line 6742 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2537,7 +2597,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6587 "reflect.h2" +#line 6772 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2546,14 +2606,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6609 "reflect.h2" +#line 6794 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6631 "reflect.h2" +#line 6816 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2574,24 +2634,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6654 "reflect.h2" +#line 6839 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6689 "reflect.h2" +#line 6874 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6703 "reflect.h2" +#line 6888 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6715 "reflect.h2" +#line 6900 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6770 "reflect.h2" +#line 6955 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2602,7 +2662,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 6896 "reflect.h2" +#line 7081 "reflect.h2" } } @@ -5545,13 +5605,209 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } #line 2438 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in decl) -> void{ + traverse(decl); + } + +#line 2442 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in decl) -> void + { + if (CPP2_UFCS(is_function)(decl)) { + pre_traverse(CPP2_UFCS(as_function)(decl)); + } + + if (CPP2_UFCS(is_object)(decl)) { + pre_traverse(CPP2_UFCS(as_object)(decl)); + } + + if (CPP2_UFCS(is_type)(decl)) { + pre_traverse(CPP2_UFCS(as_type)(decl)); + } + + // ... + // ... extend as desired to namespace, alias, etc. + // ... + } + +#line 2462 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in f) -> void{ + traverse(f); + } + +#line 2466 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in f) -> void + { + auto parameters {CPP2_UFCS(get_parameters)(f)}; + for ( auto const& param : cpp2::move(parameters) ) { + pre_traverse(param); + } + + auto returns {CPP2_UFCS(get_returns)(f)}; + for ( auto const& param : cpp2::move(returns) ) { + pre_traverse(param); + } + + if (!(CPP2_UFCS(has_compound_body)(f))) { + pre_traverse(CPP2_UFCS(get_body)(f)); + } + else { + pre_traverse(CPP2_UFCS(get_compound_body)(f)); + } + } + +#line 2487 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in o) -> void{ + traverse(o); + } + +#line 2491 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in o) -> void + { + if (CPP2_UFCS(has_initializer)(o)) { + pre_traverse(CPP2_UFCS(get_initializer)(o)); + } + } + +#line 2499 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ + traverse(t); + } + +#line 2503 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in t) -> void + { + for ( auto const& m : CPP2_UFCS(get_members)(t) ) { + pre_traverse(m); + } + } + +#line 2511 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ + traverse(t); + } + +#line 2515 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in t) -> void + { + pre_traverse(CPP2_UFCS(get_declaration)(t)); + } + +#line 2520 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ + traverse(stmt); + } + +#line 2524 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in stmt) -> void + { + if (CPP2_UFCS(is_expression_statement)(stmt)) { + pre_traverse(CPP2_UFCS(get_expression)(CPP2_UFCS(as_expression_statement)(stmt))); + } + + if (CPP2_UFCS(is_compound_statement)(stmt)) { + pre_traverse(CPP2_UFCS(as_compound_statement)(stmt)); + } + + if (CPP2_UFCS(is_selection_statement)(stmt)) + { + pre_traverse(CPP2_UFCS(as_selection_statement)(stmt)); + } + + if (CPP2_UFCS(is_declaration)(stmt)) { + pre_traverse(CPP2_UFCS(as_declaration)(stmt)); + } + + if (CPP2_UFCS(is_return_statement)(stmt)) { + pre_traverse(CPP2_UFCS(as_return_statement)(stmt)); + } + + if (CPP2_UFCS(is_iteration_statement)(stmt)) { + pre_traverse(CPP2_UFCS(as_iteration_statement)(stmt)); + } + + // TODO: + // using + // contract + // inspect + // jump + } + +#line 2559 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ + traverse(stmt); + } + +#line 2563 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in stmt) -> void + { + auto stmts {CPP2_UFCS(get_statements)(stmt)}; + + for ( auto const& cur : cpp2::move(stmts) ) { + pre_traverse(cur); + } + } + +#line 2573 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ + traverse(stmt); + } + +#line 2577 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in stmt) -> void + { + if (CPP2_UFCS(has_expression)(stmt)) { + pre_traverse(CPP2_UFCS(get_expression)(stmt)); + } + } + +#line 2585 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ + traverse(stmt); + } + +#line 2589 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in stmt) -> void + { + if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { + pre_traverse(CPP2_UFCS(get_do_while_condition)(stmt)); + pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); + } + else { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_for)(stmt)) ) { cpp2::cpp2_default.report_violation(""); } + pre_traverse(CPP2_UFCS(get_for_range)(stmt)); + pre_traverse(CPP2_UFCS(get_for_parameter)(stmt)); + pre_traverse(CPP2_UFCS(get_for_body)(stmt)); + } + + if (CPP2_UFCS(has_next)(stmt)) { + pre_traverse(CPP2_UFCS(get_next_expression)(stmt)); + } + } + +#line 2608 "reflect.h2" + auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ + traverse(stmt); + } + +#line 2612 "reflect.h2" + auto simple_traverser::traverse(cpp2::impl::in stmt) -> void + { + pre_traverse(CPP2_UFCS(get_expression)(stmt)); + pre_traverse(CPP2_UFCS(get_true_branch)(stmt)); + + if (CPP2_UFCS(has_false_branch)(stmt)) { + pre_traverse(CPP2_UFCS(get_false_branch)(stmt)); + } + } + +#line 2623 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in expr) -> void { // Nothing to select here. traverse(expr); } -#line 2444 "reflect.h2" +#line 2629 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in expr) -> void { // An expression has other shortcuts to query deeper properties, @@ -5565,7 +5821,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in pre_traverse(CPP2_UFCS(as_assignment_expression)(expr)); } -#line 2458 "reflect.h2" +#line 2643 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5583,7 +5839,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2475 "reflect.h2" +#line 2660 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5595,7 +5851,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2486 "reflect.h2" +#line 2671 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5613,7 +5869,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2503 "reflect.h2" +#line 2688 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5625,7 +5881,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2515 "reflect.h2" +#line 2700 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5643,7 +5899,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2532 "reflect.h2" +#line 2717 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5655,7 +5911,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2543 "reflect.h2" +#line 2728 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5673,7 +5929,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2560 "reflect.h2" +#line 2745 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5685,7 +5941,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2571 "reflect.h2" +#line 2756 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5703,7 +5959,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2588 "reflect.h2" +#line 2773 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5715,7 +5971,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2600 "reflect.h2" +#line 2785 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5733,7 +5989,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2617 "reflect.h2" +#line 2802 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5745,7 +6001,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2629 "reflect.h2" +#line 2814 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5763,7 +6019,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2646 "reflect.h2" +#line 2831 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5775,7 +6031,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2657 "reflect.h2" +#line 2842 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5793,7 +6049,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2674 "reflect.h2" +#line 2859 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5805,7 +6061,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2685 "reflect.h2" +#line 2870 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5823,7 +6079,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2702 "reflect.h2" +#line 2887 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5835,7 +6091,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2713 "reflect.h2" +#line 2898 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5853,7 +6109,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2730 "reflect.h2" +#line 2915 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5865,7 +6121,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2741 "reflect.h2" +#line 2926 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5883,7 +6139,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2758 "reflect.h2" +#line 2943 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5895,7 +6151,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2770 "reflect.h2" +#line 2955 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5913,7 +6169,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2787 "reflect.h2" +#line 2972 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -5925,7 +6181,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2798 "reflect.h2" +#line 2983 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -5942,7 +6198,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2814 "reflect.h2" +#line 2999 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -5954,7 +6210,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2825 "reflect.h2" +#line 3010 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in exprs) -> void { for ( auto const& expr : CPP2_UFCS(get_expressions)(exprs) ) { @@ -5962,7 +6218,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2832 "reflect.h2" +#line 3017 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -5979,13 +6235,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2848 "reflect.h2" +#line 3033 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in prefix) -> void { pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); } -#line 2853 "reflect.h2" +#line 3038 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6002,7 +6258,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2869 "reflect.h2" +#line 3054 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6022,13 +6278,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2888 "reflect.h2" +#line 3073 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in uid) -> void { static_cast(uid); } -#line 2894 "reflect.h2" +#line 3079 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in qid) -> void { for ( @@ -6038,7 +6294,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2904 "reflect.h2" +#line 3089 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in tid) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6055,7 +6311,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 2921 "reflect.h2" +#line 3106 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6075,7 +6331,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}}} } -#line 2941 "reflect.h2" +#line 3126 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in idexpr) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6092,7 +6348,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 2959 "reflect.h2" +#line 3144 "reflect.h2" //----------------------------------------------------------------------- // // sample_traverser serves two purposes: @@ -6103,7 +6359,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // for reflecting on function bodies (statements, expressions) // -#line 2969 "reflect.h2" +#line 3154 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void { sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); @@ -6125,7 +6381,7 @@ auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in f, cpp2::impl::in indent) -> void { sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); @@ -6155,7 +6411,7 @@ auto sample_traverser(cpp2::impl::in f, cpp2::impl:: } } -#line 3021 "reflect.h2" +#line 3206 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void { sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); @@ -6165,7 +6421,7 @@ auto sample_traverser(cpp2::impl::in o, cpp2::impl::in } } -#line 3031 "reflect.h2" +#line 3216 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); @@ -6175,7 +6431,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("parameter:", indent); @@ -6194,7 +6450,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl: sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); } -#line 3060 "reflect.h2" +#line 3245 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6241,7 +6497,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in stmt, cpp2::impl::in indent) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6258,7 +6514,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl: } } -#line 3124 "reflect.h2" +#line 3309 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { sample_print("return statement", indent); @@ -6268,7 +6524,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::i } } -#line 3134 "reflect.h2" +#line 3319 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6300,7 +6556,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl } } -#line 3166 "reflect.h2" +#line 3351 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void { // An expression has other shortcuts to query deeper properties, @@ -6311,7 +6567,7 @@ auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6329,7 +6585,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3193 "reflect.h2" +#line 3378 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6341,11 +6597,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3203 "reflect.h2" +#line 3388 "reflect.h2" } } -#line 3207 "reflect.h2" +#line 3392 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6363,7 +6619,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3223 "reflect.h2" +#line 3408 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6375,11 +6631,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3233 "reflect.h2" +#line 3418 "reflect.h2" } } -#line 3237 "reflect.h2" +#line 3422 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6397,7 +6653,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2 { auto first{true}; -#line 3253 "reflect.h2" +#line 3438 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6409,11 +6665,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3263 "reflect.h2" +#line 3448 "reflect.h2" } } -#line 3267 "reflect.h2" +#line 3452 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6431,7 +6687,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::imp { auto first{true}; -#line 3283 "reflect.h2" +#line 3468 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6443,11 +6699,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3293 "reflect.h2" +#line 3478 "reflect.h2" } } -#line 3297 "reflect.h2" +#line 3482 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6465,7 +6721,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3313 "reflect.h2" +#line 3498 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6477,11 +6733,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3323 "reflect.h2" +#line 3508 "reflect.h2" } } -#line 3327 "reflect.h2" +#line 3512 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6499,7 +6755,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3343 "reflect.h2" +#line 3528 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6511,11 +6767,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3353 "reflect.h2" +#line 3538 "reflect.h2" } } -#line 3357 "reflect.h2" +#line 3542 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6533,7 +6789,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3373 "reflect.h2" +#line 3558 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6545,11 +6801,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3383 "reflect.h2" +#line 3568 "reflect.h2" } } -#line 3387 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6567,7 +6823,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3403 "reflect.h2" +#line 3588 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6579,11 +6835,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3413 "reflect.h2" +#line 3598 "reflect.h2" } } -#line 3417 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6601,7 +6857,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3433 "reflect.h2" +#line 3618 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6613,11 +6869,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3443 "reflect.h2" +#line 3628 "reflect.h2" } } -#line 3447 "reflect.h2" +#line 3632 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6635,7 +6891,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl { auto first{true}; -#line 3463 "reflect.h2" +#line 3648 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6647,11 +6903,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3473 "reflect.h2" +#line 3658 "reflect.h2" } } -#line 3477 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6669,7 +6925,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3493 "reflect.h2" +#line 3678 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6681,11 +6937,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3503 "reflect.h2" +#line 3688 "reflect.h2" } } -#line 3507 "reflect.h2" +#line 3692 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6703,7 +6959,7 @@ auto sample_traverser(cpp2::impl::in binexpr, c { auto first{true}; -#line 3523 "reflect.h2" +#line 3708 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6715,11 +6971,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3533 "reflect.h2" +#line 3718 "reflect.h2" } } -#line 3537 "reflect.h2" +#line 3722 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6745,7 +7001,7 @@ auto sample_traverser(cpp2::impl::in isas, cpp2::impl::i } } -#line 3563 "reflect.h2" +#line 3748 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_empty)(exprs)) { @@ -6760,7 +7016,7 @@ auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::i } } -#line 3578 "reflect.h2" +#line 3763 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -6784,7 +7040,7 @@ auto sample_traverser(cpp2::impl::in prefix, cpp2::impl } } -#line 3602 "reflect.h2" +#line 3787 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6817,7 +7073,7 @@ auto sample_traverser(cpp2::impl::in postfix, cpp2::im } } -#line 3635 "reflect.h2" +#line 3820 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(uid)) { @@ -6828,13 +7084,13 @@ auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in qid, cpp2::impl::in indent) -> void { { auto first{true}; -#line 3649 "reflect.h2" +#line 3834 "reflect.h2" for ( auto const& term : CPP2_UFCS(get_terms)(qid) ) { @@ -6846,10 +7102,10 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_unqualified)(term), indent + 2); } } -#line 3659 "reflect.h2" +#line 3844 "reflect.h2" } -#line 3662 "reflect.h2" +#line 3847 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6866,7 +7122,7 @@ auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in primary, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6886,7 +7142,7 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im }}}} } -#line 3699 "reflect.h2" +#line 3884 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6903,42 +7159,42 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}} } -#line 3716 "reflect.h2" +#line 3901 "reflect.h2" //----------------------------------------------------------------------- // // autodiff - stub // -#line 3727 "reflect.h2" +#line 3912 "reflect.h2" // TODO: Extend -#line 3730 "reflect.h2" +#line 3915 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 3741 "reflect.h2" +#line 3926 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3743 "reflect.h2" +#line 3928 "reflect.h2" } -#line 3741 "reflect.h2" +#line 3926 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3743 "reflect.h2" +#line 3928 "reflect.h2" } -#line 3745 "reflect.h2" +#line 3930 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 3760 "reflect.h2" +#line 3945 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -6946,10 +7202,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_ } , declare_d{ declare_ }{ -#line 3765 "reflect.h2" +#line 3950 "reflect.h2" } -#line 3767 "reflect.h2" +#line 3952 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -6959,7 +7215,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 3776 "reflect.h2" +#line 3961 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -6998,7 +7254,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 3814 "reflect.h2" +#line 3999 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7014,62 +7270,62 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return true; } -#line 3829 "reflect.h2" +#line 4014 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 3833 "reflect.h2" +#line 4018 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 3837 "reflect.h2" +#line 4022 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 3841 "reflect.h2" +#line 4026 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 3845 "reflect.h2" +#line 4030 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 3849 "reflect.h2" +#line 4034 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 3853 "reflect.h2" +#line 4038 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 3857 "reflect.h2" +#line 4042 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 3861 "reflect.h2" +#line 4046 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 3865 "reflect.h2" +#line 4050 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 3869 "reflect.h2" +#line 4054 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 3873 "reflect.h2" +#line 4058 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7096,7 +7352,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 3899 "reflect.h2" +#line 4084 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7123,7 +7379,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 3926 "reflect.h2" +#line 4111 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; @@ -7141,18 +7397,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3943 "reflect.h2" +#line 4128 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 3947 "reflect.h2" +#line 4132 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); } -#line 3952 "reflect.h2" +#line 4137 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7198,14 +7454,14 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // TODO: Add function to list of functions/objects for differentiation. } -#line 4001 "reflect.h2" +#line 4186 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) : autodiff_handler_base{ ctx_ }{ -#line 4003 "reflect.h2" +#line 4188 "reflect.h2" } -#line 4005 "reflect.h2" +#line 4190 "reflect.h2" auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7235,7 +7491,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4035 "reflect.h2" +#line 4220 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7275,7 +7531,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx}; -#line 4075 "reflect.h2" +#line 4260 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { if (CPP2_UFCS(is_expression_statement)(stmt)) @@ -7382,7 +7638,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4091 "reflect.h2" +#line 4276 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -7747,7 +8003,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4456 "reflect.h2" +#line 4641 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -7763,11 +8019,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4472 "reflect.h2" +#line 4657 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4476 "reflect.h2" +#line 4661 "reflect.h2" // mod: i // mod: m // mod: s @@ -7775,116 +8031,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4485 "reflect.h2" +#line 4670 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4494 "reflect.h2" +#line 4679 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4496 "reflect.h2" +#line 4681 "reflect.h2" } -#line 4498 "reflect.h2" +#line 4683 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4500 "reflect.h2" +#line 4685 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4506 "reflect.h2" +#line 4691 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4507 "reflect.h2" +#line 4692 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4508 "reflect.h2" +#line 4693 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4523 "reflect.h2" +#line 4708 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4526 "reflect.h2" +#line 4711 "reflect.h2" } -#line 4528 "reflect.h2" +#line 4713 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4532 "reflect.h2" +#line 4717 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4544 "reflect.h2" +#line 4729 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4547 "reflect.h2" +#line 4732 "reflect.h2" } -#line 4549 "reflect.h2" +#line 4734 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4553 "reflect.h2" +#line 4738 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4563 "reflect.h2" +#line 4748 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4565 "reflect.h2" +#line 4750 "reflect.h2" } -#line 4567 "reflect.h2" +#line 4752 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4571 "reflect.h2" +#line 4756 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4583 "reflect.h2" +#line 4768 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4586 "reflect.h2" +#line 4771 "reflect.h2" } -#line 4588 "reflect.h2" +#line 4773 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4594 "reflect.h2" +#line 4779 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4600 "reflect.h2" +#line 4785 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -7893,7 +8149,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4608 "reflect.h2" +#line 4793 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -7909,7 +8165,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4636 "reflect.h2" +#line 4821 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -7917,14 +8173,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4644 "reflect.h2" +#line 4829 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4651 "reflect.h2" +#line 4836 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -7936,15 +8192,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4663 "reflect.h2" +#line 4848 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4668 "reflect.h2" +#line 4853 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4672 "reflect.h2" +#line 4857 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -7965,7 +8221,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4698 "reflect.h2" +#line 4883 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -7974,20 +8230,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4707 "reflect.h2" +#line 4892 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4713 "reflect.h2" +#line 4898 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4720 "reflect.h2" +#line 4905 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8002,16 +8258,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4750 "reflect.h2" +#line 4935 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4754 "reflect.h2" +#line 4939 "reflect.h2" } -#line 4760 "reflect.h2" +#line 4945 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8021,7 +8277,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4770 "reflect.h2" +#line 4955 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8029,17 +8285,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4777 "reflect.h2" +#line 4962 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4781 "reflect.h2" +#line 4966 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4788 "reflect.h2" +#line 4973 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8049,7 +8305,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4797 "reflect.h2" +#line 4982 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8057,24 +8313,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4804 "reflect.h2" +#line 4989 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4812 "reflect.h2" +#line 4997 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 4816 "reflect.h2" +#line 5001 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 4820 "reflect.h2" +#line 5005 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8086,22 +8342,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4831 "reflect.h2" +#line 5016 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 4837 "reflect.h2" +#line 5022 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 4841 "reflect.h2" +#line 5026 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 4845 "reflect.h2" +#line 5030 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8109,7 +8365,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4852 "reflect.h2" +#line 5037 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8121,10 +8377,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4865 "reflect.h2" +#line 5050 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 4868 "reflect.h2" +#line 5053 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8164,7 +8420,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 4908 "reflect.h2" +#line 5093 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8176,14 +8432,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4919 "reflect.h2" +#line 5104 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 4920 "reflect.h2" +#line 5105 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 4921 "reflect.h2" +#line 5106 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 4923 "reflect.h2" +#line 5108 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8193,10 +8449,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 4932 "reflect.h2" +#line 5117 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 4934 "reflect.h2" +#line 5119 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8218,14 +8474,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4955 "reflect.h2" +#line 5140 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 4956 "reflect.h2" +#line 5141 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 4957 "reflect.h2" +#line 5142 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 4959 "reflect.h2" +#line 5144 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8239,7 +8495,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 4972 "reflect.h2" +#line 5157 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8261,7 +8517,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 4993 "reflect.h2" +#line 5178 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8272,12 +8528,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5003 "reflect.h2" +#line 5188 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5004 "reflect.h2" +#line 5189 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5009 "reflect.h2" +#line 5194 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8332,7 +8588,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5063 "reflect.h2" +#line 5248 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8372,7 +8628,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5102 "reflect.h2" +#line 5287 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8388,21 +8644,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5119 "reflect.h2" +#line 5304 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5120 "reflect.h2" +#line 5305 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5121 "reflect.h2" +#line 5306 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5123 "reflect.h2" +#line 5308 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5138 "reflect.h2" +#line 5323 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8410,7 +8666,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5145 "reflect.h2" +#line 5330 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8420,22 +8676,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5163 "reflect.h2" +#line 5348 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5168 "reflect.h2" +#line 5353 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5174 "reflect.h2" +#line 5359 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5180 "reflect.h2" +#line 5365 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8444,7 +8700,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5188 "reflect.h2" +#line 5373 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8456,7 +8712,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5199 "reflect.h2" +#line 5384 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8464,7 +8720,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5206 "reflect.h2" +#line 5391 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8485,7 +8741,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5227 "reflect.h2" +#line 5412 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8495,7 +8751,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5237 "reflect.h2" +#line 5422 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8518,33 +8774,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5261 "reflect.h2" +#line 5446 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5267 "reflect.h2" +#line 5452 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5271 "reflect.h2" +#line 5456 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5277 "reflect.h2" +#line 5462 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5285 "reflect.h2" +#line 5470 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8553,7 +8809,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5293 "reflect.h2" +#line 5478 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8562,22 +8818,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5303 "reflect.h2" +#line 5488 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5307 "reflect.h2" +#line 5492 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5311 "reflect.h2" +#line 5496 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5315 "reflect.h2" +#line 5500 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8601,18 +8857,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5340 "reflect.h2" +#line 5525 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5355 "reflect.h2" +#line 5540 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5357 "reflect.h2" +#line 5542 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8623,15 +8879,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5372 "reflect.h2" +#line 5557 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5375 "reflect.h2" +#line 5560 "reflect.h2" } -#line 5377 "reflect.h2" +#line 5562 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8649,7 +8905,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5394 "reflect.h2" +#line 5579 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8657,7 +8913,7 @@ generation_function_context::generation_function_context(){} } } -#line 5401 "reflect.h2" +#line 5586 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8671,7 +8927,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5414 "reflect.h2" +#line 5599 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8687,14 +8943,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5435 "reflect.h2" +#line 5620 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5437 "reflect.h2" +#line 5622 "reflect.h2" } -#line 5439 "reflect.h2" +#line 5624 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8703,11 +8959,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5454 "reflect.h2" +#line 5639 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5456 "reflect.h2" +#line 5641 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8715,7 +8971,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5463 "reflect.h2" +#line 5648 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8724,37 +8980,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5471 "reflect.h2" +#line 5656 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5485 "reflect.h2" +#line 5670 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5489 "reflect.h2" +#line 5674 "reflect.h2" } -#line 5491 "reflect.h2" +#line 5676 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5495 "reflect.h2" +#line 5680 "reflect.h2" } -#line 5497 "reflect.h2" +#line 5682 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5501 "reflect.h2" +#line 5686 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -8763,14 +9019,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5507 "reflect.h2" +#line 5692 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5512 "reflect.h2" +#line 5697 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -8783,7 +9039,7 @@ size_t i{0}; } } -#line 5524 "reflect.h2" +#line 5709 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8805,7 +9061,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5545 "reflect.h2" +#line 5730 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -8824,7 +9080,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5563 "reflect.h2" +#line 5748 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -8840,14 +9096,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5578 "reflect.h2" +#line 5763 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5584 "reflect.h2" +#line 5769 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -8855,19 +9111,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5601 "reflect.h2" +#line 5786 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5602 "reflect.h2" +#line 5787 "reflect.h2" { -#line 5607 "reflect.h2" +#line 5792 "reflect.h2" } -#line 5610 "reflect.h2" +#line 5795 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -8993,7 +9249,7 @@ size_t i{0}; ); } -#line 5735 "reflect.h2" +#line 5920 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9003,13 +9259,13 @@ size_t i{0}; ); } -#line 5744 "reflect.h2" +#line 5929 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5749 "reflect.h2" +#line 5934 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9020,12 +9276,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5761 "reflect.h2" +#line 5946 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5766 "reflect.h2" +#line 5951 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9059,7 +9315,7 @@ size_t i{0}; } -#line 5802 "reflect.h2" +#line 5987 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9068,19 +9324,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 5825 "reflect.h2" +#line 6010 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 5826 "reflect.h2" +#line 6011 "reflect.h2" { -#line 5831 "reflect.h2" +#line 6016 "reflect.h2" } -#line 5833 "reflect.h2" +#line 6018 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9182,19 +9438,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 5934 "reflect.h2" +#line 6119 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 5938 "reflect.h2" +#line 6123 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 5962 "reflect.h2" +#line 6147 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9213,7 +9469,7 @@ size_t i{0}; return r; } -#line 5980 "reflect.h2" +#line 6165 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9228,7 +9484,7 @@ size_t i{0}; return r; } -#line 5994 "reflect.h2" +#line 6179 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9388,7 +9644,7 @@ size_t i{0}; } } -#line 6153 "reflect.h2" +#line 6338 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9397,7 +9653,7 @@ size_t i{0}; return r; } -#line 6161 "reflect.h2" +#line 6346 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9416,7 +9672,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6179 "reflect.h2" +#line 6364 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9448,7 +9704,7 @@ size_t i{0}; } } -#line 6210 "reflect.h2" +#line 6395 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9459,7 +9715,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6222 "reflect.h2" +#line 6407 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9498,7 +9754,7 @@ size_t i{0}; return r; } -#line 6263 "reflect.h2" +#line 6448 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9516,7 +9772,7 @@ size_t i{0}; }} } -#line 6283 "reflect.h2" +#line 6468 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9530,16 +9786,16 @@ size_t i{0}; } } -#line 6309 "reflect.h2" +#line 6494 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6312 "reflect.h2" +#line 6497 "reflect.h2" } -#line 6314 "reflect.h2" +#line 6499 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9551,7 +9807,7 @@ size_t i{0}; } } -#line 6325 "reflect.h2" +#line 6510 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9559,14 +9815,14 @@ size_t i{0}; return r; } -#line 6332 "reflect.h2" +#line 6517 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6340 "reflect.h2" +#line 6525 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9592,7 +9848,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6368 "reflect.h2" +#line 6553 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9618,11 +9874,11 @@ size_t i{0}; return r; } -#line 6405 "reflect.h2" +#line 6590 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6407 "reflect.h2" +#line 6592 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9696,7 +9952,7 @@ size_t i{0}; return nullptr; } -#line 6480 "reflect.h2" +#line 6665 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9709,7 +9965,7 @@ size_t i{0}; }} } -#line 6492 "reflect.h2" +#line 6677 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9723,7 +9979,7 @@ size_t i{0}; }} } -#line 6505 "reflect.h2" +#line 6690 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9743,7 +9999,7 @@ size_t i{0}; return r; } -#line 6524 "reflect.h2" +#line 6709 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -9754,7 +10010,7 @@ size_t i{0}; return r; } -#line 6534 "reflect.h2" +#line 6719 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9766,14 +10022,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6545 "reflect.h2" +#line 6730 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6557 "reflect.h2" +#line 6742 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9797,7 +10053,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6581 "reflect.h2" +#line 6766 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -9807,7 +10063,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6593 "reflect.h2" +#line 6778 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9823,7 +10079,7 @@ size_t i{0}; } } -#line 6613 "reflect.h2" +#line 6798 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9841,15 +10097,15 @@ size_t i{0}; }} } -#line 6649 "reflect.h2" +#line 6834 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6652 "reflect.h2" +#line 6837 "reflect.h2" } -#line 6654 "reflect.h2" +#line 6839 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -9885,7 +10141,7 @@ size_t i{0}; return source; } -#line 6689 "reflect.h2" +#line 6874 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -9901,7 +10157,7 @@ size_t i{0}; } } -#line 6705 "reflect.h2" +#line 6890 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -9910,7 +10166,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -9965,7 +10221,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6774 "reflect.h2" +#line 6959 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10087,7 +10343,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 6896 "reflect.h2" +#line 7081 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 8b80d565f..fb8594473 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -2435,6 +2435,191 @@ sample_print: (s: std::string_view, indent: i32) = simple_traverser: type = { + pre_traverse: (virtual inout this, decl: meta::declaration) = { + traverse(decl); + } + + traverse: (virtual inout this, decl: meta::declaration) = + { + if decl.is_function() { + pre_traverse(decl.as_function()); + } + + if decl.is_object() { + pre_traverse(decl.as_object()); + } + + if decl.is_type() { + pre_traverse(decl.as_type()); + } + + // ... + // ... extend as desired to namespace, alias, etc. + // ... + } + + + pre_traverse: (virtual inout this, f: meta::function_declaration) = { + traverse(f); + } + + traverse: (virtual inout this, f: meta::function_declaration) = + { + parameters := f.get_parameters(); + for parameters do (param) { + pre_traverse(param); + } + + returns := f.get_returns(); + for returns do (param) { + pre_traverse(param); + } + + if !f.has_compound_body() { + pre_traverse(f.get_body()); + } + else { + pre_traverse(f.get_compound_body()); + } + } + + + pre_traverse: (virtual inout this, o: meta::object_declaration) = { + traverse(o); + } + + traverse: (virtual inout this, o: meta::object_declaration) = + { + if o.has_initializer() { + pre_traverse(o.get_initializer()); + } + } + + + pre_traverse: (virtual inout this, t: meta::type_declaration) = { + traverse(t); + } + + traverse: (virtual inout this, t: meta::type_declaration) = + { + for t.get_members() do (m) { + pre_traverse(m); + } + } + + + pre_traverse: (virtual inout this, t: meta::parameter_declaration) = { + traverse(t); + } + + traverse: (virtual inout this, t: meta::parameter_declaration) = + { + pre_traverse(t.get_declaration()); + } + + pre_traverse: (virtual inout this, stmt: meta::statement) = { + traverse(stmt); + } + + traverse: (virtual inout this, stmt: meta::statement) = + { + if stmt.is_expression_statement() { + pre_traverse(stmt.as_expression_statement().get_expression()); + } + + if stmt.is_compound_statement() { + pre_traverse(stmt.as_compound_statement()); + } + + if stmt.is_selection_statement() + { + pre_traverse(stmt.as_selection_statement()); + } + + if stmt.is_declaration() { + pre_traverse(stmt.as_declaration()); + } + + if stmt.is_return_statement() { + pre_traverse(stmt.as_return_statement()); + } + + if stmt.is_iteration_statement() { + pre_traverse(stmt.as_iteration_statement()); + } + + // TODO: + // using + // contract + // inspect + // jump + } + + + pre_traverse: (virtual inout this, stmt: meta::compound_statement) = { + traverse(stmt); + } + + traverse: (virtual inout this, stmt: meta::compound_statement) = + { + stmts := stmt.get_statements(); + + for stmts do (cur) { + pre_traverse(cur); + } + } + + + pre_traverse: (virtual inout this, stmt: meta::return_statement) = { + traverse(stmt); + } + + traverse: (virtual inout this, stmt: meta::return_statement) = + { + if stmt.has_expression() { + pre_traverse(stmt.get_expression()); + } + } + + + pre_traverse: (virtual inout this, stmt: meta::iteration_statement) = { + traverse(stmt); + } + + traverse: (virtual inout this, stmt: meta::iteration_statement) = + { + if stmt.is_do() || stmt.is_while() { + pre_traverse(stmt.get_do_while_condition()); + pre_traverse(stmt.get_do_while_body()); + } + else { + assert(stmt.is_for()); + pre_traverse(stmt.get_for_range()); + pre_traverse(stmt.get_for_parameter()); + pre_traverse(stmt.get_for_body()); + } + + if stmt.has_next() { + pre_traverse(stmt.get_next_expression()); + } + } + + + pre_traverse: (virtual inout this, stmt: meta::selection_statement) = { + traverse(stmt); + } + + traverse: (virtual inout this, stmt: meta::selection_statement) = + { + pre_traverse(stmt.get_expression()); + pre_traverse(stmt.get_true_branch()); + + if stmt.has_false_branch() { + pre_traverse(stmt.get_false_branch()); + } + } + + pre_traverse: (virtual inout this, expr: meta::expression) = { // Nothing to select here. From 00be8ff639cc14e8d9213b4abd5f784beb649dbb Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 11:07:20 +0200 Subject: [PATCH 10/54] Handling if/else statements. --- regression-tests/pure2-autodiff.cpp2 | 19 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 + .../test-results/pure2-autodiff.cpp | 155 ++- .../test-results/pure2-autodiff.cpp2.output | 75 ++ source/reflect.h | 941 ++++++++++-------- source/reflect.h2 | 111 ++- 6 files changed, 844 insertions(+), 459 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 279d100b6..ea0b7c3d0 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -60,6 +60,23 @@ ad_test: @autodiff @print type = { sin_call: (x: double, y: double) -> (r: double) = { r = sin(x - y); } + + if_branch: (x: double, y: double) -> (r: double) = { + r = x; + + if x < 0.0 { + r = y; + } + } + + if_else_branch: (x: double, y: double) -> (r: double) = { + if x < 0.0 { + r = y; + } + else { + r = x; + } + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -87,4 +104,6 @@ main: () = { write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 90af526c2..8026370ae 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -12,3 +12,5 @@ diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000 diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(sin(x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index e85aa940a..d2f9053c8 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -93,6 +93,16 @@ using sin_call_ret = double; #line 60 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; +using if_branch_ret = double; + + +#line 64 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; +using if_else_branch_ret = double; + + +#line 72 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -154,17 +164,25 @@ struct sin_call_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret; +struct if_branch_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto if_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_diff_ret; + +struct if_else_branch_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 63 "pure2-autodiff.cpp2" +#line 80 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 69 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -276,82 +294,105 @@ auto main() -> int; r.construct(sin(x - y)); return std::move(r.value()); } +#line 64 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ + cpp2::impl::deferred_init r; +#line 65 "pure2-autodiff.cpp2" + r.construct(x); + + if (cpp2::impl::cmp_less(x,0.0)) { + r.value() = y; + }return std::move(r.value()); + } + +#line 72 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ + cpp2::impl::deferred_init r; +#line 73 "pure2-autodiff.cpp2" + if (cpp2::impl::cmp_less(x,0.0)) { + r.construct(y); + } + else { + r.construct(x); + }return std::move(r.value()); + } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d;r = x + y; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret{ + + [[nodiscard]] auto ad_test::add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d + x_d;r = x + y + x; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d + x_d;r = x + y + x;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret{ + + [[nodiscard]] auto ad_test::sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d - y_d;r = x - y; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d - y_d;r = x - y;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret{ + + [[nodiscard]] auto ad_test::sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d - y_d - x_d;r = x - y - x; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d - y_d - x_d;r = x - y - x;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret{ + + [[nodiscard]] auto ad_test::add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d - x_d;r = x + y - x; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d - x_d;r = x + y - x;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret{ + + [[nodiscard]] auto ad_test::mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x * y_d + y * x_d;r = x * y; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x * y_d + y * x_d;r = x * y;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret{ + + [[nodiscard]] auto ad_test::mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d);r = cpp2::move(temp_1) * x; - return { std::move(r), std::move(r_d) }; +auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d);r = cpp2::move(temp_1) * x;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret{ + + [[nodiscard]] auto ad_test::div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y);return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret{ + + [[nodiscard]] auto ad_test::div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; -auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); - return { std::move(r), std::move(r_d) }; +auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y);return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret{ + + [[nodiscard]] auto ad_test::mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); - return { std::move(r), std::move(r_d) }; +auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x);return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret{ + + [[nodiscard]] auto ad_test::mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d + y_d}; -auto temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1); - return { std::move(r), std::move(r_d) }; +auto temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret{ + + [[nodiscard]] auto ad_test::add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d);r = x + cpp2::move(temp_1); - return { std::move(r), std::move(r_d) }; +auto temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d);r = x + cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret{ + + [[nodiscard]] auto ad_test::func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d;r = x + y; - return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; } -[[nodiscard]] auto ad_test::func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret{ + + [[nodiscard]] auto ad_test::func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_2 {func_diff(x, x_d, y, y_d)}; @@ -359,8 +400,7 @@ auto temp_2 {func_diff(x, x_d, y, y_d)}; auto temp_1 {temp_2.r}; auto temp_1_d {cpp2::move(temp_2).r_d}; - r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1); - return { std::move(r), std::move(r_d) }; + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret{ @@ -369,14 +409,33 @@ auto temp_2 {func_diff(x, x_d, y, y_d)}; auto temp_1_d {x_d - y_d}; auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); r = sin(cpp2::move(temp_1)); - return { std::move(r), std::move(r_d) }; } + return { std::move(r), std::move(r_d) }; + } -#line 65 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::if_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d;r = x;if (cpp2::impl::cmp_less(x,0.0)) { + r_d = y_d;r = y;} + else { + } + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret{ + double r {0.0}; + double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { + r_d = y_d;r = y;} + else { + r_d = x_d;r = x;} + return { std::move(r), std::move(r_d) }; + } + +#line 82 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 69 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -397,6 +456,8 @@ auto main() -> int{ write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); - write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 692e7fba9..db7abdd20 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -137,6 +137,35 @@ ad_test:/* @autodiff @print */ type = return; } + if_branch:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x; + if x < 0.0 + { + r = y; + } + return; + } + + if_else_branch:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + if x < 0.0 + { + r = y; + } + else + { + r = x; + } + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -376,6 +405,52 @@ ad_test:/* @autodiff @print */ type = r = sin(temp_1); return; } + + if_branch_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x_d; + r = x; + if x < 0.0 + { + r_d = y_d; + r = y; + } + else + { + } + return; + } + + if_else_branch_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + if x < 0.0 + { + r_d = y_d; + r = y; + } + else + { + r_d = x_d; + r = x; + } + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index fa430a8aa..688f8e516 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -114,81 +114,80 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4183 "reflect.h2" +#line 4204 "reflect.h2" class autodiff_stmt_handler; - -#line 4659 "reflect.h2" +#line 4756 "reflect.h2" class expression_flags; -#line 4675 "reflect.h2" +#line 4772 "reflect.h2" class regex_token; -#line 4702 "reflect.h2" +#line 4799 "reflect.h2" class regex_token_check; -#line 4723 "reflect.h2" +#line 4820 "reflect.h2" class regex_token_code; -#line 4744 "reflect.h2" +#line 4841 "reflect.h2" class regex_token_empty; -#line 4762 "reflect.h2" +#line 4859 "reflect.h2" class regex_token_list; -#line 4814 "reflect.h2" +#line 4911 "reflect.h2" class parse_context_group_state; -#line 4875 "reflect.h2" +#line 4972 "reflect.h2" class parse_context_branch_reset_state; -#line 4918 "reflect.h2" +#line 5015 "reflect.h2" class parse_context; -#line 5319 "reflect.h2" +#line 5416 "reflect.h2" class generation_function_context; -#line 5337 "reflect.h2" +#line 5434 "reflect.h2" class generation_context; -#line 5536 "reflect.h2" +#line 5633 "reflect.h2" class alternative_token; -#line 5551 "reflect.h2" +#line 5648 "reflect.h2" class alternative_token_gen; -#line 5616 "reflect.h2" +#line 5713 "reflect.h2" class any_token; -#line 5633 "reflect.h2" +#line 5730 "reflect.h2" class atomic_group_token; -#line 5663 "reflect.h2" +#line 5760 "reflect.h2" class char_token; -#line 5778 "reflect.h2" +#line 5875 "reflect.h2" class class_token; -#line 6002 "reflect.h2" +#line 6099 "reflect.h2" class group_ref_token; -#line 6139 "reflect.h2" +#line 6236 "reflect.h2" class group_token; -#line 6486 "reflect.h2" +#line 6583 "reflect.h2" class lookahead_lookbehind_token; -#line 6581 "reflect.h2" +#line 6678 "reflect.h2" class range_token; -#line 6738 "reflect.h2" +#line 6835 "reflect.h2" class special_range_token; -#line 6824 "reflect.h2" +#line 6921 "reflect.h2" template class regex_generator; -#line 7081 "reflect.h2" +#line 7178 "reflect.h2" } } @@ -1695,33 +1694,70 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand #line 4137 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; + +#line 4182 "reflect.h2" + public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4181 "reflect.h2" +#line 4202 "reflect.h2" }; -class autodiff_stmt_handler: public autodiff_handler_base { +class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { + +#line 4208 "reflect.h2" + public: using base = simple_traverser; + + private: meta::function_declaration mf; + + public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); + +#line 4217 "reflect.h2" + public: auto traverse(cpp2::impl::in decl) -> void override; + +#line 4222 "reflect.h2" + public: auto traverse(cpp2::impl::in f) -> void override; + +#line 4227 "reflect.h2" + public: auto traverse(cpp2::impl::in o) -> void override; + +#line 4232 "reflect.h2" + public: auto traverse(cpp2::impl::in t) -> void override; -#line 4186 "reflect.h2" - public: autodiff_stmt_handler(autodiff_context* ctx_); +#line 4237 "reflect.h2" + public: auto traverse(cpp2::impl::in t) -> void override; + +#line 4242 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; + +#line 4247 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; + +#line 4255 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; + +#line 4271 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; + +#line 4276 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4190 "reflect.h2" - public: auto handle_expression_statement(auto& mf, auto const& expr) & -> void; +#line 4287 "reflect.h2" + public: auto traverse(cpp2::impl::in expr) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4218 "reflect.h2" +#line 4318 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4655 "reflect.h2" +#line 4752 "reflect.h2" using error_func = std::function x)>; -#line 4659 "reflect.h2" +#line 4756 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1756,20 +1792,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4667 "reflect.h2" +#line 4764 "reflect.h2" }; -#line 4675 "reflect.h2" +#line 4772 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4683 "reflect.h2" +#line 4780 "reflect.h2" public: explicit regex_token(); -#line 4688 "reflect.h2" +#line 4785 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1781,103 +1817,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4694 "reflect.h2" +#line 4791 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4700 "reflect.h2" +#line 4797 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4706 "reflect.h2" +#line 4803 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4713 "reflect.h2" +#line 4810 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4717 "reflect.h2" +#line 4814 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4718 "reflect.h2" +#line 4815 "reflect.h2" }; -#line 4721 "reflect.h2" +#line 4818 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4727 "reflect.h2" +#line 4824 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4734 "reflect.h2" +#line 4831 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4738 "reflect.h2" +#line 4835 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4739 "reflect.h2" +#line 4836 "reflect.h2" }; -#line 4742 "reflect.h2" +#line 4839 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4748 "reflect.h2" +#line 4845 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4752 "reflect.h2" +#line 4849 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4756 "reflect.h2" +#line 4853 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4757 "reflect.h2" +#line 4854 "reflect.h2" }; -#line 4760 "reflect.h2" +#line 4857 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4766 "reflect.h2" +#line 4863 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4773 "reflect.h2" +#line 4870 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4779 "reflect.h2" +#line 4876 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4785 "reflect.h2" +#line 4882 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4793 "reflect.h2" +#line 4890 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1885,10 +1921,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4805 "reflect.h2" +#line 4902 "reflect.h2" }; -#line 4808 "reflect.h2" +#line 4905 "reflect.h2" // // Parse and generation context. // @@ -1904,33 +1940,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4828 "reflect.h2" +#line 4925 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4835 "reflect.h2" +#line 4932 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4847 "reflect.h2" +#line 4944 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4852 "reflect.h2" +#line 4949 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4856 "reflect.h2" +#line 4953 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4870 "reflect.h2" +#line 4967 "reflect.h2" }; -#line 4873 "reflect.h2" +#line 4970 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1943,25 +1979,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4891 "reflect.h2" +#line 4988 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4897 "reflect.h2" +#line 4994 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 4904 "reflect.h2" +#line 5001 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 4911 "reflect.h2" +#line 5008 "reflect.h2" }; -#line 4914 "reflect.h2" +#line 5011 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -1977,7 +2013,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 4930 "reflect.h2" +#line 5027 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -1985,64 +2021,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 4941 "reflect.h2" +#line 5038 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 4954 "reflect.h2" +#line 5051 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 4962 "reflect.h2" +#line 5059 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 4966 "reflect.h2" +#line 5063 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 4970 "reflect.h2" +#line 5067 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 4982 "reflect.h2" +#line 5079 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 4989 "reflect.h2" +#line 5086 "reflect.h2" public: auto next_alternative() & -> void; -#line 4995 "reflect.h2" +#line 5092 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5001 "reflect.h2" +#line 5098 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5005 "reflect.h2" +#line 5102 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5016 "reflect.h2" +#line 5113 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5020 "reflect.h2" +#line 5117 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5026 "reflect.h2" +#line 5123 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5030 "reflect.h2" +#line 5127 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5037 "reflect.h2" +#line 5134 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5048 "reflect.h2" +#line 5145 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2050,51 +2086,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5092 "reflect.h2" +#line 5189 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5104 "reflect.h2" +#line 5201 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5117 "reflect.h2" +#line 5214 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5140 "reflect.h2" +#line 5237 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5157 "reflect.h2" +#line 5254 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5178 "reflect.h2" +#line 5275 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5188 "reflect.h2" +#line 5285 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5192 "reflect.h2" +#line 5289 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5248 "reflect.h2" +#line 5345 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5287 "reflect.h2" +#line 5384 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5302 "reflect.h2" +#line 5399 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2106,10 +2142,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5313 "reflect.h2" +#line 5410 "reflect.h2" }; -#line 5316 "reflect.h2" +#line 5413 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2119,16 +2155,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5330 "reflect.h2" +#line 5427 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5333 "reflect.h2" +#line 5430 "reflect.h2" }; -#line 5336 "reflect.h2" +#line 5433 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2148,68 +2184,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5358 "reflect.h2" +#line 5455 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5364 "reflect.h2" +#line 5461 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5373 "reflect.h2" +#line 5470 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5384 "reflect.h2" +#line 5481 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5391 "reflect.h2" +#line 5488 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5411 "reflect.h2" +#line 5508 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5421 "reflect.h2" +#line 5518 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5444 "reflect.h2" +#line 5541 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5452 "reflect.h2" +#line 5549 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5456 "reflect.h2" +#line 5553 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5462 "reflect.h2" +#line 5559 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5468 "reflect.h2" +#line 5565 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5478 "reflect.h2" +#line 5575 "reflect.h2" public: auto finish_context() & -> void; -#line 5486 "reflect.h2" +#line 5583 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5492 "reflect.h2" +#line 5589 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5496 "reflect.h2" +#line 5593 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5500 "reflect.h2" +#line 5597 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5524 "reflect.h2" +#line 5621 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2217,7 +2253,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5530 "reflect.h2" +#line 5627 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2237,27 +2273,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5549 "reflect.h2" +#line 5646 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5555 "reflect.h2" +#line 5652 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5562 "reflect.h2" +#line 5659 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5579 "reflect.h2" +#line 5676 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5586 "reflect.h2" +#line 5683 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5599 "reflect.h2" +#line 5696 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2265,19 +2301,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5611 "reflect.h2" +#line 5708 "reflect.h2" }; -#line 5614 "reflect.h2" +#line 5711 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5620 "reflect.h2" +#line 5717 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5624 "reflect.h2" +#line 5721 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2285,7 +2321,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5629 "reflect.h2" +#line 5726 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2293,17 +2329,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5637 "reflect.h2" +#line 5734 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5648 "reflect.h2" +#line 5745 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5656 "reflect.h2" +#line 5753 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2311,7 +2347,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5659 "reflect.h2" +#line 5756 "reflect.h2" }; // Regex syntax: a @@ -2319,34 +2355,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5667 "reflect.h2" +#line 5764 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5676 "reflect.h2" +#line 5773 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5682 "reflect.h2" +#line 5779 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5686 "reflect.h2" +#line 5783 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5709 "reflect.h2" +#line 5806 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5730 "reflect.h2" +#line 5827 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5748 "reflect.h2" +#line 5845 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5763 "reflect.h2" +#line 5860 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5769 "reflect.h2" +#line 5866 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2354,33 +2390,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5773 "reflect.h2" +#line 5870 "reflect.h2" }; -#line 5776 "reflect.h2" +#line 5873 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5782 "reflect.h2" +#line 5879 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5794 "reflect.h2" +#line 5891 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5920 "reflect.h2" +#line 6017 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5929 "reflect.h2" +#line 6026 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5934 "reflect.h2" +#line 6031 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2388,20 +2424,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 5941 "reflect.h2" +#line 6038 "reflect.h2" }; -#line 5944 "reflect.h2" +#line 6041 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 5985 "reflect.h2" +#line 6082 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 5996 "reflect.h2" +#line 6093 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2411,20 +2447,20 @@ class class_token class group_ref_token : public regex_token { -#line 6006 "reflect.h2" +#line 6103 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6018 "reflect.h2" +#line 6115 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6119 "reflect.h2" +#line 6216 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6123 "reflect.h2" +#line 6220 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2432,10 +2468,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6126 "reflect.h2" +#line 6223 "reflect.h2" }; -#line 6129 "reflect.h2" +#line 6226 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2449,29 +2485,29 @@ class group_ref_token class group_token : public regex_token { -#line 6143 "reflect.h2" +#line 6240 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6165 "reflect.h2" +#line 6262 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6179 "reflect.h2" +#line 6276 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6338 "reflect.h2" +#line 6435 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6346 "reflect.h2" +#line 6443 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6364 "reflect.h2" +#line 6461 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6395 "reflect.h2" +#line 6492 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2480,25 +2516,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6402 "reflect.h2" +#line 6499 "reflect.h2" }; -#line 6405 "reflect.h2" +#line 6502 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6446 "reflect.h2" +#line 6543 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6466 "reflect.h2" +#line 6563 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6482 "reflect.h2" +#line 6579 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2506,20 +2542,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6490 "reflect.h2" +#line 6587 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6499 "reflect.h2" +#line 6596 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6510 "reflect.h2" +#line 6607 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6517 "reflect.h2" +#line 6614 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2527,26 +2563,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6520 "reflect.h2" +#line 6617 "reflect.h2" }; -#line 6523 "reflect.h2" +#line 6620 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6551 "reflect.h2" +#line 6648 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6579 "reflect.h2" +#line 6676 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6585 "reflect.h2" +#line 6682 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2556,22 +2592,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6665 "reflect.h2" +#line 6762 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6677 "reflect.h2" +#line 6774 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6690 "reflect.h2" +#line 6787 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6709 "reflect.h2" +#line 6806 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6719 "reflect.h2" +#line 6816 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6730 "reflect.h2" +#line 6827 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2579,16 +2615,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6733 "reflect.h2" +#line 6830 "reflect.h2" }; -#line 6736 "reflect.h2" +#line 6833 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6742 "reflect.h2" +#line 6839 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2597,7 +2633,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6772 "reflect.h2" +#line 6869 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2606,14 +2642,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6794 "reflect.h2" +#line 6891 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6816 "reflect.h2" +#line 6913 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2634,24 +2670,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6839 "reflect.h2" +#line 6936 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6874 "reflect.h2" +#line 6971 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6888 "reflect.h2" +#line 6985 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6900 "reflect.h2" +#line 6997 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 6955 "reflect.h2" +#line 7052 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2662,7 +2698,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7081 "reflect.h2" +#line 7178 "reflect.h2" } } @@ -7454,15 +7490,110 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // TODO: Add function to list of functions/objects for differentiation. } -#line 4186 "reflect.h2" - autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_) - : autodiff_handler_base{ ctx_ }{ +#line 4182 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void + { + if (CPP2_UFCS(is_identifier)(primary)) { + diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + "_d;"; + diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ";"; + } + else {if (CPP2_UFCS(is_expression_list)(primary)) { + CPP2_UFCS(error)(primary, "AD: Do not know how to handle expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + } + else {if (CPP2_UFCS(is_literal)(primary)) { + diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= ();"; + diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ";"; + } + else {if (CPP2_UFCS(is_declaration)(primary)) { + CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + } + else { + CPP2_UFCS(error)(primary, "AD: Unknown primary expression kind: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + }}}} + } -#line 4188 "reflect.h2" +#line 4212 "reflect.h2" + autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) + : simple_traverser{ } + , autodiff_handler_base{ ctx_ } + , mf{ mf_ }{ + +#line 4215 "reflect.h2" + } + +#line 4217 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ + CPP2_UFCS(error)(decl, "AD: Do not know how to handle declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(decl)) + ""); + } + +#line 4222 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ + CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); + } + +#line 4227 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ + CPP2_UFCS(error)(o, "AD: Do not know how to handle object_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(o)) + ""); + } + +#line 4232 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ + CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); + } + +#line 4237 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ + CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); + } + +#line 4242 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + base::traverse(stmt); + } + +#line 4247 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + // Brackets are handled by the + diff += "{\n"; + base::traverse(stmt); + diff += "}\n"; + } + +#line 4255 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + if (CPP2_UFCS(has_expression)(stmt)) { + // Return with expression. + // TODO: Remove assumptions + // - Return expression is always active. (Look this up in mf or so.) + // - Return was converted to a two parameter return with the name r. + autodiff_expression_handler ad {ctx, "r"}; + ad.pre_traverse(CPP2_UFCS(get_expression)(stmt)); + append(cpp2::move(ad)); + } + else { + diff += "return;\n"; + } + } + +#line 4271 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + CPP2_UFCS(error)(stmt, "AD: Do not know how to handle iteration_statement: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); + } + +#line 4276 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + // TODO: Currently assuming that nothing bad happens in the condition + diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; + pre_traverse(CPP2_UFCS(get_true_branch)(stmt)); + + if (CPP2_UFCS(has_false_branch)(stmt)) { + diff += "else "; + pre_traverse(CPP2_UFCS(get_false_branch)(stmt)); + } } -#line 4190 "reflect.h2" - auto autodiff_stmt_handler::handle_expression_statement(auto& mf, auto const& expr) & -> void{ +#line 4287 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { // If this is not an assignment to a parameter or return object, skip it @@ -7489,9 +7620,12 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in append(cpp2::move(h)); } + else { + CPP2_UFCS(error)(mf, "AD: Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(expr)) + ""); + } } -#line 4220 "reflect.h2" +#line 4320 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7529,15 +7663,12 @@ auto autodiff(meta::type_declaration& t) -> void } autodiff_context ad_ctx {}; - autodiff_stmt_handler ad_impl {&ad_ctx}; + autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4260 "reflect.h2" - for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) +#line 4360 "reflect.h2" + for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { - if (CPP2_UFCS(is_expression_statement)(stmt)) - { - CPP2_UFCS(handle_expression_statement)(ad_impl, mf, CPP2_UFCS(get_expression)(CPP2_UFCS(as_expression_statement)(stmt))); - } + ad_impl.pre_traverse(stmt); } diff += cpp2::move(ad_impl).diff; @@ -7638,7 +7769,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4276 "reflect.h2" +#line 4373 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8003,7 +8134,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4641 "reflect.h2" +#line 4738 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8019,11 +8150,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4657 "reflect.h2" +#line 4754 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4661 "reflect.h2" +#line 4758 "reflect.h2" // mod: i // mod: m // mod: s @@ -8031,116 +8162,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4670 "reflect.h2" +#line 4767 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4679 "reflect.h2" +#line 4776 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4681 "reflect.h2" +#line 4778 "reflect.h2" } -#line 4683 "reflect.h2" +#line 4780 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4685 "reflect.h2" +#line 4782 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4691 "reflect.h2" +#line 4788 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4692 "reflect.h2" +#line 4789 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4693 "reflect.h2" +#line 4790 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4708 "reflect.h2" +#line 4805 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4711 "reflect.h2" +#line 4808 "reflect.h2" } -#line 4713 "reflect.h2" +#line 4810 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4717 "reflect.h2" +#line 4814 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4729 "reflect.h2" +#line 4826 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4732 "reflect.h2" +#line 4829 "reflect.h2" } -#line 4734 "reflect.h2" +#line 4831 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4738 "reflect.h2" +#line 4835 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4748 "reflect.h2" +#line 4845 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4750 "reflect.h2" +#line 4847 "reflect.h2" } -#line 4752 "reflect.h2" +#line 4849 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4756 "reflect.h2" +#line 4853 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4768 "reflect.h2" +#line 4865 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4771 "reflect.h2" +#line 4868 "reflect.h2" } -#line 4773 "reflect.h2" +#line 4870 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4779 "reflect.h2" +#line 4876 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4785 "reflect.h2" +#line 4882 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8149,7 +8280,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4793 "reflect.h2" +#line 4890 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8165,7 +8296,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4821 "reflect.h2" +#line 4918 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8173,14 +8304,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4829 "reflect.h2" +#line 4926 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4836 "reflect.h2" +#line 4933 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8192,15 +8323,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4848 "reflect.h2" +#line 4945 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4853 "reflect.h2" +#line 4950 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4857 "reflect.h2" +#line 4954 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8221,7 +8352,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4883 "reflect.h2" +#line 4980 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8230,20 +8361,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4892 "reflect.h2" +#line 4989 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4898 "reflect.h2" +#line 4995 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 4905 "reflect.h2" +#line 5002 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8258,16 +8389,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 4935 "reflect.h2" +#line 5032 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 4939 "reflect.h2" +#line 5036 "reflect.h2" } -#line 4945 "reflect.h2" +#line 5042 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8277,7 +8408,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4955 "reflect.h2" +#line 5052 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8285,17 +8416,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 4962 "reflect.h2" +#line 5059 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 4966 "reflect.h2" +#line 5063 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 4973 "reflect.h2" +#line 5070 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8305,7 +8436,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 4982 "reflect.h2" +#line 5079 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8313,24 +8444,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 4989 "reflect.h2" +#line 5086 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 4997 "reflect.h2" +#line 5094 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5001 "reflect.h2" +#line 5098 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5005 "reflect.h2" +#line 5102 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8342,22 +8473,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5016 "reflect.h2" +#line 5113 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5022 "reflect.h2" +#line 5119 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5026 "reflect.h2" +#line 5123 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5030 "reflect.h2" +#line 5127 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8365,7 +8496,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5037 "reflect.h2" +#line 5134 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8377,10 +8508,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5050 "reflect.h2" +#line 5147 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5053 "reflect.h2" +#line 5150 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8420,7 +8551,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5093 "reflect.h2" +#line 5190 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8432,14 +8563,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5104 "reflect.h2" +#line 5201 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5105 "reflect.h2" +#line 5202 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5106 "reflect.h2" +#line 5203 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5108 "reflect.h2" +#line 5205 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8449,10 +8580,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5117 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5119 "reflect.h2" +#line 5216 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8474,14 +8605,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5140 "reflect.h2" +#line 5237 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5141 "reflect.h2" +#line 5238 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5142 "reflect.h2" +#line 5239 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5144 "reflect.h2" +#line 5241 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8495,7 +8626,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5157 "reflect.h2" +#line 5254 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8517,7 +8648,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5178 "reflect.h2" +#line 5275 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8528,12 +8659,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5188 "reflect.h2" +#line 5285 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5189 "reflect.h2" +#line 5286 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5194 "reflect.h2" +#line 5291 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8588,7 +8719,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5248 "reflect.h2" +#line 5345 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8628,7 +8759,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5287 "reflect.h2" +#line 5384 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8644,21 +8775,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5304 "reflect.h2" +#line 5401 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5305 "reflect.h2" +#line 5402 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5306 "reflect.h2" +#line 5403 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5308 "reflect.h2" +#line 5405 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5323 "reflect.h2" +#line 5420 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8666,7 +8797,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5330 "reflect.h2" +#line 5427 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8676,22 +8807,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5348 "reflect.h2" +#line 5445 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5353 "reflect.h2" +#line 5450 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5359 "reflect.h2" +#line 5456 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5365 "reflect.h2" +#line 5462 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8700,7 +8831,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5373 "reflect.h2" +#line 5470 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8712,7 +8843,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5384 "reflect.h2" +#line 5481 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8720,7 +8851,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5391 "reflect.h2" +#line 5488 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8741,7 +8872,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5412 "reflect.h2" +#line 5509 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8751,7 +8882,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5422 "reflect.h2" +#line 5519 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8774,33 +8905,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5446 "reflect.h2" +#line 5543 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5452 "reflect.h2" +#line 5549 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5456 "reflect.h2" +#line 5553 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5462 "reflect.h2" +#line 5559 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5470 "reflect.h2" +#line 5567 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8809,7 +8940,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5478 "reflect.h2" +#line 5575 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8818,22 +8949,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5488 "reflect.h2" +#line 5585 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5492 "reflect.h2" +#line 5589 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5496 "reflect.h2" +#line 5593 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5500 "reflect.h2" +#line 5597 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8857,18 +8988,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5525 "reflect.h2" +#line 5622 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5540 "reflect.h2" +#line 5637 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5542 "reflect.h2" +#line 5639 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -8879,15 +9010,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5557 "reflect.h2" +#line 5654 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5560 "reflect.h2" +#line 5657 "reflect.h2" } -#line 5562 "reflect.h2" +#line 5659 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -8905,7 +9036,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5579 "reflect.h2" +#line 5676 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -8913,7 +9044,7 @@ generation_function_context::generation_function_context(){} } } -#line 5586 "reflect.h2" +#line 5683 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -8927,7 +9058,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5599 "reflect.h2" +#line 5696 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -8943,14 +9074,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5620 "reflect.h2" +#line 5717 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5622 "reflect.h2" +#line 5719 "reflect.h2" } -#line 5624 "reflect.h2" +#line 5721 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -8959,11 +9090,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5639 "reflect.h2" +#line 5736 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5641 "reflect.h2" +#line 5738 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -8971,7 +9102,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5648 "reflect.h2" +#line 5745 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -8980,37 +9111,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5656 "reflect.h2" +#line 5753 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5670 "reflect.h2" +#line 5767 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5674 "reflect.h2" +#line 5771 "reflect.h2" } -#line 5676 "reflect.h2" +#line 5773 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5680 "reflect.h2" +#line 5777 "reflect.h2" } -#line 5682 "reflect.h2" +#line 5779 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5686 "reflect.h2" +#line 5783 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9019,14 +9150,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5692 "reflect.h2" +#line 5789 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5697 "reflect.h2" +#line 5794 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9039,7 +9170,7 @@ size_t i{0}; } } -#line 5709 "reflect.h2" +#line 5806 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9061,7 +9192,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5730 "reflect.h2" +#line 5827 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9080,7 +9211,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5748 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9096,14 +9227,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5763 "reflect.h2" +#line 5860 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5769 "reflect.h2" +#line 5866 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9111,19 +9242,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5786 "reflect.h2" +#line 5883 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5787 "reflect.h2" +#line 5884 "reflect.h2" { -#line 5792 "reflect.h2" +#line 5889 "reflect.h2" } -#line 5795 "reflect.h2" +#line 5892 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9249,7 +9380,7 @@ size_t i{0}; ); } -#line 5920 "reflect.h2" +#line 6017 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9259,13 +9390,13 @@ size_t i{0}; ); } -#line 5929 "reflect.h2" +#line 6026 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 5934 "reflect.h2" +#line 6031 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9276,12 +9407,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 5946 "reflect.h2" +#line 6043 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 5951 "reflect.h2" +#line 6048 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9315,7 +9446,7 @@ size_t i{0}; } -#line 5987 "reflect.h2" +#line 6084 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9324,19 +9455,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6010 "reflect.h2" +#line 6107 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6011 "reflect.h2" +#line 6108 "reflect.h2" { -#line 6016 "reflect.h2" +#line 6113 "reflect.h2" } -#line 6018 "reflect.h2" +#line 6115 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9438,19 +9569,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6119 "reflect.h2" +#line 6216 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6123 "reflect.h2" +#line 6220 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6147 "reflect.h2" +#line 6244 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9469,7 +9600,7 @@ size_t i{0}; return r; } -#line 6165 "reflect.h2" +#line 6262 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9484,7 +9615,7 @@ size_t i{0}; return r; } -#line 6179 "reflect.h2" +#line 6276 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9644,7 +9775,7 @@ size_t i{0}; } } -#line 6338 "reflect.h2" +#line 6435 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9653,7 +9784,7 @@ size_t i{0}; return r; } -#line 6346 "reflect.h2" +#line 6443 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9672,7 +9803,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6364 "reflect.h2" +#line 6461 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9704,7 +9835,7 @@ size_t i{0}; } } -#line 6395 "reflect.h2" +#line 6492 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9715,7 +9846,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6407 "reflect.h2" +#line 6504 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9754,7 +9885,7 @@ size_t i{0}; return r; } -#line 6448 "reflect.h2" +#line 6545 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9772,7 +9903,7 @@ size_t i{0}; }} } -#line 6468 "reflect.h2" +#line 6565 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9786,16 +9917,16 @@ size_t i{0}; } } -#line 6494 "reflect.h2" +#line 6591 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6497 "reflect.h2" +#line 6594 "reflect.h2" } -#line 6499 "reflect.h2" +#line 6596 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9807,7 +9938,7 @@ size_t i{0}; } } -#line 6510 "reflect.h2" +#line 6607 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9815,14 +9946,14 @@ size_t i{0}; return r; } -#line 6517 "reflect.h2" +#line 6614 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6525 "reflect.h2" +#line 6622 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9848,7 +9979,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6553 "reflect.h2" +#line 6650 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -9874,11 +10005,11 @@ size_t i{0}; return r; } -#line 6590 "reflect.h2" +#line 6687 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6592 "reflect.h2" +#line 6689 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -9952,7 +10083,7 @@ size_t i{0}; return nullptr; } -#line 6665 "reflect.h2" +#line 6762 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -9965,7 +10096,7 @@ size_t i{0}; }} } -#line 6677 "reflect.h2" +#line 6774 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -9979,7 +10110,7 @@ size_t i{0}; }} } -#line 6690 "reflect.h2" +#line 6787 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -9999,7 +10130,7 @@ size_t i{0}; return r; } -#line 6709 "reflect.h2" +#line 6806 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10010,7 +10141,7 @@ size_t i{0}; return r; } -#line 6719 "reflect.h2" +#line 6816 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10022,14 +10153,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6730 "reflect.h2" +#line 6827 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6742 "reflect.h2" +#line 6839 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10053,7 +10184,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6766 "reflect.h2" +#line 6863 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10063,7 +10194,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6778 "reflect.h2" +#line 6875 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10079,7 +10210,7 @@ size_t i{0}; } } -#line 6798 "reflect.h2" +#line 6895 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10097,15 +10228,15 @@ size_t i{0}; }} } -#line 6834 "reflect.h2" +#line 6931 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6837 "reflect.h2" +#line 6934 "reflect.h2" } -#line 6839 "reflect.h2" +#line 6936 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10141,7 +10272,7 @@ size_t i{0}; return source; } -#line 6874 "reflect.h2" +#line 6971 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10157,7 +10288,7 @@ size_t i{0}; } } -#line 6890 "reflect.h2" +#line 6987 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10166,7 +10297,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10221,7 +10352,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 6959 "reflect.h2" +#line 7056 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10343,7 +10474,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7081 "reflect.h2" +#line 7178 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index fb8594473..47955a872 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4178,16 +4178,113 @@ autodiff_expression_handler: type = { // TODO: Add function to list of functions/objects for differentiation. } + + traverse: (override inout this, primary: meta::primary_expression) = + { + if primary.is_identifier() { + diff += "(lhs)$_d (declare_p)$= (primary.to_string())$_d;"; + diff += "(lhs)$ (declare_d)$= (primary.to_string())$;"; + } + else if primary.is_expression_list() { + primary.error("AD: Do not know how to handle expression list inside of primary_expression: (primary.to_string())$"); + } + else if primary.is_literal() { + diff += "(lhs)$_d (declare_p)$= ();"; + diff += "(lhs)$ (declare_d)$= (primary.to_string())$;"; + } + else if primary.is_declaration() { + primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); + } + else { + primary.error("AD: Unknown primary expression kind: (primary.to_string())$"); + } + } } autodiff_stmt_handler: type = { + this: simple_traverser = (); this: autodiff_handler_base; - operator=: (out this, ctx_: *autodiff_context) = { + base: type == simple_traverser; + + mf: meta::function_declaration; + + operator=: (out this, ctx_: *autodiff_context, mf_: meta::function_declaration) = { autodiff_handler_base = (ctx_); + mf = mf_; + } + + traverse: (override inout this, decl: meta::declaration) = { + decl.error("AD: Do not know how to handle declaration: (decl.to_string())$"); + } + + + traverse: (override inout this, f: meta::function_declaration) = { + f.error("AD: Do not know how to handle function_declaration: (f.to_string())$"); + } + + + traverse: (override inout this, o: meta::object_declaration) = { + o.error("AD: Do not know how to handle object_declaration: (o.to_string())$"); + } + + + traverse: (override inout this, t: meta::type_declaration) = { + t.error("AD: Do not know how to handle type_declaration: (t.to_string())$"); + } + + + traverse: (override inout this, t: meta::parameter_declaration) = { + t.error("AD: Do not know how to handle parameter_declaration: (t.to_string())$"); + } + + + traverse: (override inout this, stmt: meta::statement) = { + base::traverse(stmt); + } + + + traverse: (override inout this, stmt: meta::compound_statement) = { + // Brackets are handled by the + diff += "{\n"; + base::traverse(stmt); + diff += "}\n"; + } + + + traverse: (override inout this, stmt: meta::return_statement) = { + if stmt.has_expression() { + // Return with expression. + // TODO: Remove assumptions + // - Return expression is always active. (Look this up in mf or so.) + // - Return was converted to a two parameter return with the name r. + ad: autodiff_expression_handler = (ctx, "r"); + ad..pre_traverse(stmt.get_expression()); + append(ad); + } + else { + diff += "return;\n"; + } } - handle_expression_statement : (inout this, inout mf, expr) = { + + traverse: (override inout this, stmt: meta::iteration_statement) = { + stmt.error("AD: Do not know how to handle iteration_statement: (stmt.to_string())$"); + } + + + traverse: (override inout this, stmt: meta::selection_statement) = { + // TODO: Currently assuming that nothing bad happens in the condition + diff += "if (stmt.get_expression().to_string())$"; + pre_traverse(stmt.get_true_branch()); + + if stmt.has_false_branch() { + diff += "else "; + pre_traverse(stmt.get_false_branch()); + } + } + + traverse : (override inout this, expr: meta::expression) = { if expr.is_simple_assignment() { // If this is not an assignment to a parameter or return object, skip it @@ -4214,6 +4311,9 @@ autodiff_stmt_handler: type = { append(h); } + else { + mf.error("AD: Do not know how to handle: (expr.to_string())$"); + } } } @@ -4254,15 +4354,12 @@ autodiff: (inout t: meta::type_declaration) = } ad_ctx: autodiff_context = (); - ad_impl : autodiff_stmt_handler = (ad_ctx&); + ad_impl : autodiff_stmt_handler = (ad_ctx&, mf); for mf.get_compound_body().get_statements() do (stmt) { - if stmt.is_expression_statement() - { - ad_impl.handle_expression_statement(mf, stmt.as_expression_statement().get_expression()); - } + ad_impl..pre_traverse(stmt); } diff += ad_impl.diff; From dad71ef4af86a986633150f014204acfd87355b1 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 11:49:01 +0200 Subject: [PATCH 11/54] Added handling of direct return. --- regression-tests/pure2-autodiff.cpp2 | 5 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 29 +- .../test-results/pure2-autodiff.cpp2.output | 23 + source/reflect.h | 784 +++++++++--------- source/reflect.h2 | 18 +- 6 files changed, 466 insertions(+), 394 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index ea0b7c3d0..d061fbe85 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -77,6 +77,10 @@ ad_test: @autodiff @print type = { r = x; } } + + direct_return: (x: double, y: double) -> double = { + return x + y; + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -106,4 +110,5 @@ main: () = { write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 8026370ae..b6cabc801 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -14,3 +14,4 @@ diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000 diff(sin(x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index d2f9053c8..bd2b36fa7 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -103,6 +103,9 @@ using if_else_branch_ret = double; #line 72 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; + +#line 81 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; struct add_1_diff_ret { double r; double r_d; }; @@ -172,17 +175,21 @@ struct if_else_branch_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret; +struct direct_return_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 80 "pure2-autodiff.cpp2" +#line 84 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 86 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -317,6 +324,11 @@ auto main() -> int; }return std::move(r.value()); } +#line 81 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ + return x + y; + } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; @@ -430,12 +442,18 @@ auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); return { std::move(r), std::move(r_d) }; } -#line 82 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret{ + double r {}; + double r_d {};r_d = x_d + y_d;r = x + y; + return { std::move(r), std::move(r_d) }; + } + +#line 86 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 86 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -458,6 +476,7 @@ auto main() -> int{ write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index db7abdd20..25080d865 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -166,6 +166,14 @@ ad_test:/* @autodiff @print */ type = return; } + direct_return:( + in x: double, + in y: double, + ) -> move double = + { + return x + y; + } + add_1_diff:( in x: double, in x_d: double, @@ -451,6 +459,21 @@ ad_test:/* @autodiff @print */ type = } return; } + + direct_return_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = (), + out r_d: double = (), + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 688f8e516..6cc539993 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -117,77 +117,77 @@ class autodiff_expression_handler; #line 4204 "reflect.h2" class autodiff_stmt_handler; -#line 4756 "reflect.h2" +#line 4768 "reflect.h2" class expression_flags; -#line 4772 "reflect.h2" +#line 4784 "reflect.h2" class regex_token; -#line 4799 "reflect.h2" +#line 4811 "reflect.h2" class regex_token_check; -#line 4820 "reflect.h2" +#line 4832 "reflect.h2" class regex_token_code; -#line 4841 "reflect.h2" +#line 4853 "reflect.h2" class regex_token_empty; -#line 4859 "reflect.h2" +#line 4871 "reflect.h2" class regex_token_list; -#line 4911 "reflect.h2" +#line 4923 "reflect.h2" class parse_context_group_state; -#line 4972 "reflect.h2" +#line 4984 "reflect.h2" class parse_context_branch_reset_state; -#line 5015 "reflect.h2" +#line 5027 "reflect.h2" class parse_context; -#line 5416 "reflect.h2" +#line 5428 "reflect.h2" class generation_function_context; -#line 5434 "reflect.h2" +#line 5446 "reflect.h2" class generation_context; -#line 5633 "reflect.h2" +#line 5645 "reflect.h2" class alternative_token; -#line 5648 "reflect.h2" +#line 5660 "reflect.h2" class alternative_token_gen; -#line 5713 "reflect.h2" +#line 5725 "reflect.h2" class any_token; -#line 5730 "reflect.h2" +#line 5742 "reflect.h2" class atomic_group_token; -#line 5760 "reflect.h2" +#line 5772 "reflect.h2" class char_token; -#line 5875 "reflect.h2" +#line 5887 "reflect.h2" class class_token; -#line 6099 "reflect.h2" +#line 6111 "reflect.h2" class group_ref_token; -#line 6236 "reflect.h2" +#line 6248 "reflect.h2" class group_token; -#line 6583 "reflect.h2" +#line 6595 "reflect.h2" class lookahead_lookbehind_token; -#line 6678 "reflect.h2" +#line 6690 "reflect.h2" class range_token; -#line 6835 "reflect.h2" +#line 6847 "reflect.h2" class special_range_token; -#line 6921 "reflect.h2" +#line 6933 "reflect.h2" template class regex_generator; -#line 7178 "reflect.h2" +#line 7190 "reflect.h2" } } @@ -1754,10 +1754,10 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba auto autodiff(meta::type_declaration& t) -> void; -#line 4752 "reflect.h2" +#line 4764 "reflect.h2" using error_func = std::function x)>; -#line 4756 "reflect.h2" +#line 4768 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1792,20 +1792,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4764 "reflect.h2" +#line 4776 "reflect.h2" }; -#line 4772 "reflect.h2" +#line 4784 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4780 "reflect.h2" +#line 4792 "reflect.h2" public: explicit regex_token(); -#line 4785 "reflect.h2" +#line 4797 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1817,103 +1817,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4791 "reflect.h2" +#line 4803 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4797 "reflect.h2" +#line 4809 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4803 "reflect.h2" +#line 4815 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4810 "reflect.h2" +#line 4822 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4814 "reflect.h2" +#line 4826 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4815 "reflect.h2" +#line 4827 "reflect.h2" }; -#line 4818 "reflect.h2" +#line 4830 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4824 "reflect.h2" +#line 4836 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4831 "reflect.h2" +#line 4843 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4835 "reflect.h2" +#line 4847 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4836 "reflect.h2" +#line 4848 "reflect.h2" }; -#line 4839 "reflect.h2" +#line 4851 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4845 "reflect.h2" +#line 4857 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4849 "reflect.h2" +#line 4861 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4853 "reflect.h2" +#line 4865 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4854 "reflect.h2" +#line 4866 "reflect.h2" }; -#line 4857 "reflect.h2" +#line 4869 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4863 "reflect.h2" +#line 4875 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4870 "reflect.h2" +#line 4882 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4876 "reflect.h2" +#line 4888 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4882 "reflect.h2" +#line 4894 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4890 "reflect.h2" +#line 4902 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1921,10 +1921,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4902 "reflect.h2" +#line 4914 "reflect.h2" }; -#line 4905 "reflect.h2" +#line 4917 "reflect.h2" // // Parse and generation context. // @@ -1940,33 +1940,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4925 "reflect.h2" +#line 4937 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4932 "reflect.h2" +#line 4944 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4944 "reflect.h2" +#line 4956 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4949 "reflect.h2" +#line 4961 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4953 "reflect.h2" +#line 4965 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4967 "reflect.h2" +#line 4979 "reflect.h2" }; -#line 4970 "reflect.h2" +#line 4982 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1979,25 +1979,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 4988 "reflect.h2" +#line 5000 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 4994 "reflect.h2" +#line 5006 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5001 "reflect.h2" +#line 5013 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5008 "reflect.h2" +#line 5020 "reflect.h2" }; -#line 5011 "reflect.h2" +#line 5023 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2013,7 +2013,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5027 "reflect.h2" +#line 5039 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2021,64 +2021,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5038 "reflect.h2" +#line 5050 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5051 "reflect.h2" +#line 5063 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5059 "reflect.h2" +#line 5071 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5063 "reflect.h2" +#line 5075 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5067 "reflect.h2" +#line 5079 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5079 "reflect.h2" +#line 5091 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5086 "reflect.h2" +#line 5098 "reflect.h2" public: auto next_alternative() & -> void; -#line 5092 "reflect.h2" +#line 5104 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5098 "reflect.h2" +#line 5110 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5102 "reflect.h2" +#line 5114 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5113 "reflect.h2" +#line 5125 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5117 "reflect.h2" +#line 5129 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5123 "reflect.h2" +#line 5135 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5127 "reflect.h2" +#line 5139 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5134 "reflect.h2" +#line 5146 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5145 "reflect.h2" +#line 5157 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2086,51 +2086,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5189 "reflect.h2" +#line 5201 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5201 "reflect.h2" +#line 5213 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5214 "reflect.h2" +#line 5226 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5237 "reflect.h2" +#line 5249 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5254 "reflect.h2" +#line 5266 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5275 "reflect.h2" +#line 5287 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5285 "reflect.h2" +#line 5297 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5289 "reflect.h2" +#line 5301 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5345 "reflect.h2" +#line 5357 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5384 "reflect.h2" +#line 5396 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5399 "reflect.h2" +#line 5411 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2142,10 +2142,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5410 "reflect.h2" +#line 5422 "reflect.h2" }; -#line 5413 "reflect.h2" +#line 5425 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2155,16 +2155,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5427 "reflect.h2" +#line 5439 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5430 "reflect.h2" +#line 5442 "reflect.h2" }; -#line 5433 "reflect.h2" +#line 5445 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2184,68 +2184,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5455 "reflect.h2" +#line 5467 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5461 "reflect.h2" +#line 5473 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5470 "reflect.h2" +#line 5482 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5481 "reflect.h2" +#line 5493 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5488 "reflect.h2" +#line 5500 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5508 "reflect.h2" +#line 5520 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5518 "reflect.h2" +#line 5530 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5541 "reflect.h2" +#line 5553 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5549 "reflect.h2" +#line 5561 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5553 "reflect.h2" +#line 5565 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5559 "reflect.h2" +#line 5571 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5565 "reflect.h2" +#line 5577 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5575 "reflect.h2" +#line 5587 "reflect.h2" public: auto finish_context() & -> void; -#line 5583 "reflect.h2" +#line 5595 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5589 "reflect.h2" +#line 5601 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5593 "reflect.h2" +#line 5605 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5597 "reflect.h2" +#line 5609 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5621 "reflect.h2" +#line 5633 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2253,7 +2253,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5627 "reflect.h2" +#line 5639 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2273,27 +2273,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5646 "reflect.h2" +#line 5658 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5652 "reflect.h2" +#line 5664 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5659 "reflect.h2" +#line 5671 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5676 "reflect.h2" +#line 5688 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5683 "reflect.h2" +#line 5695 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5696 "reflect.h2" +#line 5708 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2301,19 +2301,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5708 "reflect.h2" +#line 5720 "reflect.h2" }; -#line 5711 "reflect.h2" +#line 5723 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5717 "reflect.h2" +#line 5729 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5721 "reflect.h2" +#line 5733 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2321,7 +2321,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5726 "reflect.h2" +#line 5738 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2329,17 +2329,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5734 "reflect.h2" +#line 5746 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5745 "reflect.h2" +#line 5757 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5753 "reflect.h2" +#line 5765 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2347,7 +2347,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5756 "reflect.h2" +#line 5768 "reflect.h2" }; // Regex syntax: a @@ -2355,34 +2355,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5764 "reflect.h2" +#line 5776 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5773 "reflect.h2" +#line 5785 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5779 "reflect.h2" +#line 5791 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5783 "reflect.h2" +#line 5795 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5806 "reflect.h2" +#line 5818 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5827 "reflect.h2" +#line 5839 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5845 "reflect.h2" +#line 5857 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5860 "reflect.h2" +#line 5872 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5866 "reflect.h2" +#line 5878 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2390,33 +2390,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5870 "reflect.h2" +#line 5882 "reflect.h2" }; -#line 5873 "reflect.h2" +#line 5885 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5879 "reflect.h2" +#line 5891 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5891 "reflect.h2" +#line 5903 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6017 "reflect.h2" +#line 6029 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6026 "reflect.h2" +#line 6038 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6031 "reflect.h2" +#line 6043 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2424,20 +2424,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6038 "reflect.h2" +#line 6050 "reflect.h2" }; -#line 6041 "reflect.h2" +#line 6053 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6082 "reflect.h2" +#line 6094 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6093 "reflect.h2" +#line 6105 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2447,20 +2447,20 @@ class class_token class group_ref_token : public regex_token { -#line 6103 "reflect.h2" +#line 6115 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6115 "reflect.h2" +#line 6127 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6216 "reflect.h2" +#line 6228 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6220 "reflect.h2" +#line 6232 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2468,10 +2468,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6223 "reflect.h2" +#line 6235 "reflect.h2" }; -#line 6226 "reflect.h2" +#line 6238 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2485,29 +2485,29 @@ class group_ref_token class group_token : public regex_token { -#line 6240 "reflect.h2" +#line 6252 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6262 "reflect.h2" +#line 6274 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6276 "reflect.h2" +#line 6288 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6435 "reflect.h2" +#line 6447 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6443 "reflect.h2" +#line 6455 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6461 "reflect.h2" +#line 6473 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6492 "reflect.h2" +#line 6504 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2516,25 +2516,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6499 "reflect.h2" +#line 6511 "reflect.h2" }; -#line 6502 "reflect.h2" +#line 6514 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6543 "reflect.h2" +#line 6555 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6563 "reflect.h2" +#line 6575 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6579 "reflect.h2" +#line 6591 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2542,20 +2542,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6587 "reflect.h2" +#line 6599 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6596 "reflect.h2" +#line 6608 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6607 "reflect.h2" +#line 6619 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6614 "reflect.h2" +#line 6626 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2563,26 +2563,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6617 "reflect.h2" +#line 6629 "reflect.h2" }; -#line 6620 "reflect.h2" +#line 6632 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6648 "reflect.h2" +#line 6660 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6676 "reflect.h2" +#line 6688 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6682 "reflect.h2" +#line 6694 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2592,22 +2592,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6762 "reflect.h2" +#line 6774 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6774 "reflect.h2" +#line 6786 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6787 "reflect.h2" +#line 6799 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6806 "reflect.h2" +#line 6818 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6816 "reflect.h2" +#line 6828 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6827 "reflect.h2" +#line 6839 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2615,16 +2615,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6830 "reflect.h2" +#line 6842 "reflect.h2" }; -#line 6833 "reflect.h2" +#line 6845 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6839 "reflect.h2" +#line 6851 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2633,7 +2633,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6869 "reflect.h2" +#line 6881 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2642,14 +2642,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6891 "reflect.h2" +#line 6903 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6913 "reflect.h2" +#line 6925 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2670,24 +2670,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6936 "reflect.h2" +#line 6948 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6971 "reflect.h2" +#line 6983 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6985 "reflect.h2" +#line 6997 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 6997 "reflect.h2" +#line 7009 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7052 "reflect.h2" +#line 7064 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2698,7 +2698,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7178 "reflect.h2" +#line 7190 "reflect.h2" } } @@ -7648,9 +7648,21 @@ auto autodiff(meta::type_declaration& t) -> void // b) Returns - for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + if (CPP2_UFCS(has_non_void_return_type)(mf) && CPP2_UFCS(empty)(CPP2_UFCS(get_returns)(mf))) {// TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) + if (CPP2_UFCS(has_deduced_return_type)(mf)) { + // TODO: Take care of initialization order error. + diff += "r, r_d, "; + } + else { + diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r_d: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), "; + } + } + else { + for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + } } diff += ") = {"; @@ -7665,7 +7677,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4360 "reflect.h2" +#line 4372 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -7769,7 +7781,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4373 "reflect.h2" +#line 4385 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8134,7 +8146,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4738 "reflect.h2" +#line 4750 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8150,11 +8162,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4754 "reflect.h2" +#line 4766 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4758 "reflect.h2" +#line 4770 "reflect.h2" // mod: i // mod: m // mod: s @@ -8162,116 +8174,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4767 "reflect.h2" +#line 4779 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4776 "reflect.h2" +#line 4788 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4778 "reflect.h2" +#line 4790 "reflect.h2" } -#line 4780 "reflect.h2" +#line 4792 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4782 "reflect.h2" +#line 4794 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4788 "reflect.h2" +#line 4800 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4789 "reflect.h2" +#line 4801 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4790 "reflect.h2" +#line 4802 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4805 "reflect.h2" +#line 4817 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4808 "reflect.h2" +#line 4820 "reflect.h2" } -#line 4810 "reflect.h2" +#line 4822 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4814 "reflect.h2" +#line 4826 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4826 "reflect.h2" +#line 4838 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4829 "reflect.h2" +#line 4841 "reflect.h2" } -#line 4831 "reflect.h2" +#line 4843 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4835 "reflect.h2" +#line 4847 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4845 "reflect.h2" +#line 4857 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4847 "reflect.h2" +#line 4859 "reflect.h2" } -#line 4849 "reflect.h2" +#line 4861 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4853 "reflect.h2" +#line 4865 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4865 "reflect.h2" +#line 4877 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4868 "reflect.h2" +#line 4880 "reflect.h2" } -#line 4870 "reflect.h2" +#line 4882 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4876 "reflect.h2" +#line 4888 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4882 "reflect.h2" +#line 4894 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8280,7 +8292,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4890 "reflect.h2" +#line 4902 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8296,7 +8308,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4918 "reflect.h2" +#line 4930 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8304,14 +8316,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4926 "reflect.h2" +#line 4938 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4933 "reflect.h2" +#line 4945 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8323,15 +8335,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4945 "reflect.h2" +#line 4957 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4950 "reflect.h2" +#line 4962 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4954 "reflect.h2" +#line 4966 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8352,7 +8364,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4980 "reflect.h2" +#line 4992 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8361,20 +8373,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 4989 "reflect.h2" +#line 5001 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 4995 "reflect.h2" +#line 5007 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5002 "reflect.h2" +#line 5014 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8389,16 +8401,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5032 "reflect.h2" +#line 5044 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5036 "reflect.h2" +#line 5048 "reflect.h2" } -#line 5042 "reflect.h2" +#line 5054 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8408,7 +8420,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5052 "reflect.h2" +#line 5064 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8416,17 +8428,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5059 "reflect.h2" +#line 5071 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5063 "reflect.h2" +#line 5075 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5070 "reflect.h2" +#line 5082 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8436,7 +8448,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5079 "reflect.h2" +#line 5091 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8444,24 +8456,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5086 "reflect.h2" +#line 5098 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5094 "reflect.h2" +#line 5106 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5098 "reflect.h2" +#line 5110 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5102 "reflect.h2" +#line 5114 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8473,22 +8485,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5113 "reflect.h2" +#line 5125 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5119 "reflect.h2" +#line 5131 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5123 "reflect.h2" +#line 5135 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5127 "reflect.h2" +#line 5139 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8496,7 +8508,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5134 "reflect.h2" +#line 5146 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8508,10 +8520,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5147 "reflect.h2" +#line 5159 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5150 "reflect.h2" +#line 5162 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8551,7 +8563,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5190 "reflect.h2" +#line 5202 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8563,14 +8575,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5201 "reflect.h2" +#line 5213 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5202 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5203 "reflect.h2" +#line 5215 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5205 "reflect.h2" +#line 5217 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8580,10 +8592,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5214 "reflect.h2" +#line 5226 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5216 "reflect.h2" +#line 5228 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8605,14 +8617,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5237 "reflect.h2" +#line 5249 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5238 "reflect.h2" +#line 5250 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5239 "reflect.h2" +#line 5251 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5241 "reflect.h2" +#line 5253 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8626,7 +8638,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5254 "reflect.h2" +#line 5266 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8648,7 +8660,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5275 "reflect.h2" +#line 5287 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8659,12 +8671,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5285 "reflect.h2" +#line 5297 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5286 "reflect.h2" +#line 5298 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5291 "reflect.h2" +#line 5303 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8719,7 +8731,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5345 "reflect.h2" +#line 5357 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8759,7 +8771,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5384 "reflect.h2" +#line 5396 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8775,21 +8787,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5401 "reflect.h2" +#line 5413 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5402 "reflect.h2" +#line 5414 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5403 "reflect.h2" +#line 5415 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5405 "reflect.h2" +#line 5417 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5420 "reflect.h2" +#line 5432 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8797,7 +8809,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5427 "reflect.h2" +#line 5439 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8807,22 +8819,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5445 "reflect.h2" +#line 5457 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5450 "reflect.h2" +#line 5462 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5456 "reflect.h2" +#line 5468 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5462 "reflect.h2" +#line 5474 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8831,7 +8843,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5470 "reflect.h2" +#line 5482 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8843,7 +8855,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5481 "reflect.h2" +#line 5493 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8851,7 +8863,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5488 "reflect.h2" +#line 5500 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8872,7 +8884,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5509 "reflect.h2" +#line 5521 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8882,7 +8894,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5519 "reflect.h2" +#line 5531 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8905,33 +8917,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5543 "reflect.h2" +#line 5555 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5549 "reflect.h2" +#line 5561 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5553 "reflect.h2" +#line 5565 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5559 "reflect.h2" +#line 5571 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5567 "reflect.h2" +#line 5579 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8940,7 +8952,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5575 "reflect.h2" +#line 5587 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8949,22 +8961,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5585 "reflect.h2" +#line 5597 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5589 "reflect.h2" +#line 5601 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5593 "reflect.h2" +#line 5605 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5597 "reflect.h2" +#line 5609 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -8988,18 +9000,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5622 "reflect.h2" +#line 5634 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5637 "reflect.h2" +#line 5649 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5639 "reflect.h2" +#line 5651 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9010,15 +9022,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5654 "reflect.h2" +#line 5666 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5657 "reflect.h2" +#line 5669 "reflect.h2" } -#line 5659 "reflect.h2" +#line 5671 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9036,7 +9048,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5676 "reflect.h2" +#line 5688 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9044,7 +9056,7 @@ generation_function_context::generation_function_context(){} } } -#line 5683 "reflect.h2" +#line 5695 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9058,7 +9070,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5696 "reflect.h2" +#line 5708 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9074,14 +9086,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5717 "reflect.h2" +#line 5729 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5719 "reflect.h2" +#line 5731 "reflect.h2" } -#line 5721 "reflect.h2" +#line 5733 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9090,11 +9102,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5736 "reflect.h2" +#line 5748 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5738 "reflect.h2" +#line 5750 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9102,7 +9114,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5745 "reflect.h2" +#line 5757 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9111,37 +9123,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5753 "reflect.h2" +#line 5765 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5767 "reflect.h2" +#line 5779 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5771 "reflect.h2" +#line 5783 "reflect.h2" } -#line 5773 "reflect.h2" +#line 5785 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5777 "reflect.h2" +#line 5789 "reflect.h2" } -#line 5779 "reflect.h2" +#line 5791 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5783 "reflect.h2" +#line 5795 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9150,14 +9162,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5789 "reflect.h2" +#line 5801 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5794 "reflect.h2" +#line 5806 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9170,7 +9182,7 @@ size_t i{0}; } } -#line 5806 "reflect.h2" +#line 5818 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9192,7 +9204,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5827 "reflect.h2" +#line 5839 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9211,7 +9223,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5845 "reflect.h2" +#line 5857 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9227,14 +9239,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5860 "reflect.h2" +#line 5872 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5866 "reflect.h2" +#line 5878 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9242,19 +9254,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5883 "reflect.h2" +#line 5895 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5884 "reflect.h2" +#line 5896 "reflect.h2" { -#line 5889 "reflect.h2" +#line 5901 "reflect.h2" } -#line 5892 "reflect.h2" +#line 5904 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9380,7 +9392,7 @@ size_t i{0}; ); } -#line 6017 "reflect.h2" +#line 6029 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9390,13 +9402,13 @@ size_t i{0}; ); } -#line 6026 "reflect.h2" +#line 6038 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6031 "reflect.h2" +#line 6043 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9407,12 +9419,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6043 "reflect.h2" +#line 6055 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6048 "reflect.h2" +#line 6060 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9446,7 +9458,7 @@ size_t i{0}; } -#line 6084 "reflect.h2" +#line 6096 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9455,19 +9467,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6107 "reflect.h2" +#line 6119 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6108 "reflect.h2" +#line 6120 "reflect.h2" { -#line 6113 "reflect.h2" +#line 6125 "reflect.h2" } -#line 6115 "reflect.h2" +#line 6127 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9569,19 +9581,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6216 "reflect.h2" +#line 6228 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6220 "reflect.h2" +#line 6232 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6244 "reflect.h2" +#line 6256 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9600,7 +9612,7 @@ size_t i{0}; return r; } -#line 6262 "reflect.h2" +#line 6274 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9615,7 +9627,7 @@ size_t i{0}; return r; } -#line 6276 "reflect.h2" +#line 6288 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9775,7 +9787,7 @@ size_t i{0}; } } -#line 6435 "reflect.h2" +#line 6447 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9784,7 +9796,7 @@ size_t i{0}; return r; } -#line 6443 "reflect.h2" +#line 6455 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9803,7 +9815,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6461 "reflect.h2" +#line 6473 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9835,7 +9847,7 @@ size_t i{0}; } } -#line 6492 "reflect.h2" +#line 6504 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9846,7 +9858,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6504 "reflect.h2" +#line 6516 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9885,7 +9897,7 @@ size_t i{0}; return r; } -#line 6545 "reflect.h2" +#line 6557 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9903,7 +9915,7 @@ size_t i{0}; }} } -#line 6565 "reflect.h2" +#line 6577 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9917,16 +9929,16 @@ size_t i{0}; } } -#line 6591 "reflect.h2" +#line 6603 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6594 "reflect.h2" +#line 6606 "reflect.h2" } -#line 6596 "reflect.h2" +#line 6608 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9938,7 +9950,7 @@ size_t i{0}; } } -#line 6607 "reflect.h2" +#line 6619 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9946,14 +9958,14 @@ size_t i{0}; return r; } -#line 6614 "reflect.h2" +#line 6626 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6622 "reflect.h2" +#line 6634 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9979,7 +9991,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6650 "reflect.h2" +#line 6662 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10005,11 +10017,11 @@ size_t i{0}; return r; } -#line 6687 "reflect.h2" +#line 6699 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6689 "reflect.h2" +#line 6701 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10083,7 +10095,7 @@ size_t i{0}; return nullptr; } -#line 6762 "reflect.h2" +#line 6774 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10096,7 +10108,7 @@ size_t i{0}; }} } -#line 6774 "reflect.h2" +#line 6786 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10110,7 +10122,7 @@ size_t i{0}; }} } -#line 6787 "reflect.h2" +#line 6799 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10130,7 +10142,7 @@ size_t i{0}; return r; } -#line 6806 "reflect.h2" +#line 6818 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10141,7 +10153,7 @@ size_t i{0}; return r; } -#line 6816 "reflect.h2" +#line 6828 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10153,14 +10165,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6827 "reflect.h2" +#line 6839 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6839 "reflect.h2" +#line 6851 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10184,7 +10196,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6863 "reflect.h2" +#line 6875 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10194,7 +10206,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6875 "reflect.h2" +#line 6887 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10210,7 +10222,7 @@ size_t i{0}; } } -#line 6895 "reflect.h2" +#line 6907 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10228,15 +10240,15 @@ size_t i{0}; }} } -#line 6931 "reflect.h2" +#line 6943 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6934 "reflect.h2" +#line 6946 "reflect.h2" } -#line 6936 "reflect.h2" +#line 6948 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10272,7 +10284,7 @@ size_t i{0}; return source; } -#line 6971 "reflect.h2" +#line 6983 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10288,7 +10300,7 @@ size_t i{0}; } } -#line 6987 "reflect.h2" +#line 6999 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10297,7 +10309,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10352,7 +10364,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7056 "reflect.h2" +#line 7068 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10474,7 +10486,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7178 "reflect.h2" +#line 7190 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 47955a872..f2c550123 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4339,9 +4339,21 @@ autodiff: (inout t: meta::type_declaration) = // b) Returns - for mf.get_returns() do (param) { - diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$ = 0.0, "; + if mf.has_non_void_return_type() && mf.get_returns().empty() { // TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) + if mf.has_deduced_return_type() { + // TODO: Take care of initialization order error. + diff += "r, r_d, "; + } + else { + diff += "r: (mf.get_unnamed_return_type())$ = (), r_d: (mf.get_unnamed_return_type())$ = (), "; + } + } + else { + for mf.get_returns() do (param) { + diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; + diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$ = 0.0, "; + } } diff += ") = {"; From e1ab97b473f83de4eaaa14d906052fad403b0b3d Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 13:16:10 +0200 Subject: [PATCH 12/54] Stub handling of value declarations. --- regression-tests/pure2-autodiff.cpp2 | 8 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 38 +- .../test-results/pure2-autodiff.cpp2.output | 30 + source/reflect.h | 962 +++++++++--------- source/reflect.h2 | 24 +- 6 files changed, 579 insertions(+), 484 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index d061fbe85..b0ec3ac91 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -81,6 +81,13 @@ ad_test: @autodiff @print type = { direct_return: (x: double, y: double) -> double = { return x + y; } + + intermediate_var: (x: double, y: double) -> (r: double) = { + t: double = (); // TODO: change to x initializer when we have access to the initializer expression. + t = x + y; + + r = t; + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -111,4 +118,5 @@ main: () = { write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index b6cabc801..23f0c0aa4 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -15,3 +15,4 @@ diff(sin(x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index bd2b36fa7..893766212 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -106,6 +106,11 @@ using if_else_branch_ret = double; #line 81 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; +using intermediate_var_ret = double; + + +#line 85 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -179,17 +184,21 @@ struct direct_return_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret; +struct intermediate_var_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 84 "pure2-autodiff.cpp2" +#line 91 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 90 "pure2-autodiff.cpp2" +#line 97 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -329,6 +338,16 @@ auto main() -> int; return x + y; } +#line 85 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ + cpp2::impl::deferred_init r; +#line 86 "pure2-autodiff.cpp2" + double t {}; // TODO: change to x initializer when we have access to the initializer expression. + t = x + y; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; @@ -447,13 +466,21 @@ auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); double r_d {};r_d = x_d + y_d;r = x + y; return { std::move(r), std::move(r_d) }; } +[[nodiscard]] auto ad_test::intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret{ + double r {0.0}; + double r_d {0.0}; +double t_d {}; -#line 86 "pure2-autodiff.cpp2" + double t {}; + t_d = x_d + y_d;t = x + y;r_d = cpp2::move(t_d);r = cpp2::move(t);return { std::move(r), std::move(r_d) }; + } + +#line 93 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 90 "pure2-autodiff.cpp2" +#line 97 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -477,6 +504,7 @@ auto main() -> int{ write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 25080d865..d56b690e2 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -174,6 +174,17 @@ ad_test:/* @autodiff @print */ type = return x + y; } + intermediate_var:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: double = (); + t = x + y; + r = t; + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -474,6 +485,25 @@ ad_test:/* @autodiff @print */ type = r = x + y; return; } + + intermediate_var_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + t_d: double = (); + t: double = (); + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 6cc539993..5a9d15558 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -106,88 +106,88 @@ class simple_traverser; class autodiff_context; -#line 3921 "reflect.h2" +#line 3929 "reflect.h2" class autodiff_handler_base; -#line 3935 "reflect.h2" +#line 3943 "reflect.h2" class autodiff_expression_handler; -#line 4204 "reflect.h2" +#line 4212 "reflect.h2" class autodiff_stmt_handler; -#line 4768 "reflect.h2" +#line 4780 "reflect.h2" class expression_flags; -#line 4784 "reflect.h2" +#line 4796 "reflect.h2" class regex_token; -#line 4811 "reflect.h2" +#line 4823 "reflect.h2" class regex_token_check; -#line 4832 "reflect.h2" +#line 4844 "reflect.h2" class regex_token_code; -#line 4853 "reflect.h2" +#line 4865 "reflect.h2" class regex_token_empty; -#line 4871 "reflect.h2" +#line 4883 "reflect.h2" class regex_token_list; -#line 4923 "reflect.h2" +#line 4935 "reflect.h2" class parse_context_group_state; -#line 4984 "reflect.h2" +#line 4996 "reflect.h2" class parse_context_branch_reset_state; -#line 5027 "reflect.h2" +#line 5039 "reflect.h2" class parse_context; -#line 5428 "reflect.h2" +#line 5440 "reflect.h2" class generation_function_context; -#line 5446 "reflect.h2" +#line 5458 "reflect.h2" class generation_context; -#line 5645 "reflect.h2" +#line 5657 "reflect.h2" class alternative_token; -#line 5660 "reflect.h2" +#line 5672 "reflect.h2" class alternative_token_gen; -#line 5725 "reflect.h2" +#line 5737 "reflect.h2" class any_token; -#line 5742 "reflect.h2" +#line 5754 "reflect.h2" class atomic_group_token; -#line 5772 "reflect.h2" +#line 5784 "reflect.h2" class char_token; -#line 5887 "reflect.h2" +#line 5899 "reflect.h2" class class_token; -#line 6111 "reflect.h2" +#line 6123 "reflect.h2" class group_ref_token; -#line 6248 "reflect.h2" +#line 6260 "reflect.h2" class group_token; -#line 6595 "reflect.h2" +#line 6607 "reflect.h2" class lookahead_lookbehind_token; -#line 6690 "reflect.h2" +#line 6702 "reflect.h2" class range_token; -#line 6847 "reflect.h2" +#line 6859 "reflect.h2" class special_range_token; -#line 6933 "reflect.h2" +#line 6945 "reflect.h2" template class regex_generator; -#line 7190 "reflect.h2" +#line 7202 "reflect.h2" } } @@ -1601,12 +1601,15 @@ class autodiff_context { #line 3915 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; + +#line 3921 "reflect.h2" + public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3919 "reflect.h2" +#line 3927 "reflect.h2" }; class autodiff_handler_base { @@ -1615,21 +1618,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3926 "reflect.h2" +#line 3934 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3930 "reflect.h2" +#line 3938 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3933 "reflect.h2" +#line 3941 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3939 "reflect.h2" +#line 3947 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1638,126 +1641,126 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3952 "reflect.h2" +#line 3960 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 3961 "reflect.h2" +#line 3969 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 3999 "reflect.h2" +#line 4007 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 4014 "reflect.h2" +#line 4022 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4018 "reflect.h2" +#line 4026 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4022 "reflect.h2" +#line 4030 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4026 "reflect.h2" +#line 4034 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4030 "reflect.h2" +#line 4038 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4034 "reflect.h2" +#line 4042 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4038 "reflect.h2" +#line 4046 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4042 "reflect.h2" +#line 4050 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4046 "reflect.h2" +#line 4054 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4050 "reflect.h2" +#line 4058 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4054 "reflect.h2" +#line 4062 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4058 "reflect.h2" +#line 4066 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4084 "reflect.h2" +#line 4092 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4128 "reflect.h2" +#line 4136 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4132 "reflect.h2" +#line 4140 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4137 "reflect.h2" +#line 4145 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4182 "reflect.h2" +#line 4190 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4202 "reflect.h2" +#line 4210 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4208 "reflect.h2" +#line 4216 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4217 "reflect.h2" +#line 4225 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4222 "reflect.h2" +#line 4230 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4227 "reflect.h2" +#line 4235 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4232 "reflect.h2" +#line 4248 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4237 "reflect.h2" +#line 4253 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4242 "reflect.h2" +#line 4258 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4247 "reflect.h2" +#line 4263 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4255 "reflect.h2" +#line 4271 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4271 "reflect.h2" +#line 4287 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4276 "reflect.h2" +#line 4292 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4287 "reflect.h2" +#line 4303 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4318 "reflect.h2" +#line 4330 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4764 "reflect.h2" +#line 4776 "reflect.h2" using error_func = std::function x)>; -#line 4768 "reflect.h2" +#line 4780 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1792,20 +1795,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4776 "reflect.h2" +#line 4788 "reflect.h2" }; -#line 4784 "reflect.h2" +#line 4796 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4792 "reflect.h2" +#line 4804 "reflect.h2" public: explicit regex_token(); -#line 4797 "reflect.h2" +#line 4809 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1817,103 +1820,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4803 "reflect.h2" +#line 4815 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4809 "reflect.h2" +#line 4821 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4815 "reflect.h2" +#line 4827 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4822 "reflect.h2" +#line 4834 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4826 "reflect.h2" +#line 4838 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4827 "reflect.h2" +#line 4839 "reflect.h2" }; -#line 4830 "reflect.h2" +#line 4842 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4836 "reflect.h2" +#line 4848 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4843 "reflect.h2" +#line 4855 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4847 "reflect.h2" +#line 4859 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4848 "reflect.h2" +#line 4860 "reflect.h2" }; -#line 4851 "reflect.h2" +#line 4863 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4857 "reflect.h2" +#line 4869 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4861 "reflect.h2" +#line 4873 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4865 "reflect.h2" +#line 4877 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4866 "reflect.h2" +#line 4878 "reflect.h2" }; -#line 4869 "reflect.h2" +#line 4881 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4875 "reflect.h2" +#line 4887 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4882 "reflect.h2" +#line 4894 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4888 "reflect.h2" +#line 4900 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4894 "reflect.h2" +#line 4906 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4902 "reflect.h2" +#line 4914 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1921,10 +1924,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4914 "reflect.h2" +#line 4926 "reflect.h2" }; -#line 4917 "reflect.h2" +#line 4929 "reflect.h2" // // Parse and generation context. // @@ -1940,33 +1943,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4937 "reflect.h2" +#line 4949 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4944 "reflect.h2" +#line 4956 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4956 "reflect.h2" +#line 4968 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4961 "reflect.h2" +#line 4973 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4965 "reflect.h2" +#line 4977 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4979 "reflect.h2" +#line 4991 "reflect.h2" }; -#line 4982 "reflect.h2" +#line 4994 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1979,25 +1982,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5000 "reflect.h2" +#line 5012 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5006 "reflect.h2" +#line 5018 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5013 "reflect.h2" +#line 5025 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5020 "reflect.h2" +#line 5032 "reflect.h2" }; -#line 5023 "reflect.h2" +#line 5035 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2013,7 +2016,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5039 "reflect.h2" +#line 5051 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2021,64 +2024,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5050 "reflect.h2" +#line 5062 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5063 "reflect.h2" +#line 5075 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5071 "reflect.h2" +#line 5083 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5075 "reflect.h2" +#line 5087 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5079 "reflect.h2" +#line 5091 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5091 "reflect.h2" +#line 5103 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5098 "reflect.h2" +#line 5110 "reflect.h2" public: auto next_alternative() & -> void; -#line 5104 "reflect.h2" +#line 5116 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5110 "reflect.h2" +#line 5122 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5114 "reflect.h2" +#line 5126 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5125 "reflect.h2" +#line 5137 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5129 "reflect.h2" +#line 5141 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5135 "reflect.h2" +#line 5147 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5139 "reflect.h2" +#line 5151 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5146 "reflect.h2" +#line 5158 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5157 "reflect.h2" +#line 5169 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2086,51 +2089,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5201 "reflect.h2" +#line 5213 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5213 "reflect.h2" +#line 5225 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5226 "reflect.h2" +#line 5238 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5249 "reflect.h2" +#line 5261 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5266 "reflect.h2" +#line 5278 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5287 "reflect.h2" +#line 5299 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5297 "reflect.h2" +#line 5309 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5301 "reflect.h2" +#line 5313 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5357 "reflect.h2" +#line 5369 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5396 "reflect.h2" +#line 5408 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5411 "reflect.h2" +#line 5423 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2142,10 +2145,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5422 "reflect.h2" +#line 5434 "reflect.h2" }; -#line 5425 "reflect.h2" +#line 5437 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2155,16 +2158,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5439 "reflect.h2" +#line 5451 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5442 "reflect.h2" +#line 5454 "reflect.h2" }; -#line 5445 "reflect.h2" +#line 5457 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2184,68 +2187,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5467 "reflect.h2" +#line 5479 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5473 "reflect.h2" +#line 5485 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5482 "reflect.h2" +#line 5494 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5493 "reflect.h2" +#line 5505 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5500 "reflect.h2" +#line 5512 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5520 "reflect.h2" +#line 5532 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5530 "reflect.h2" +#line 5542 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5553 "reflect.h2" +#line 5565 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5561 "reflect.h2" +#line 5573 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5565 "reflect.h2" +#line 5577 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5571 "reflect.h2" +#line 5583 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5577 "reflect.h2" +#line 5589 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5587 "reflect.h2" +#line 5599 "reflect.h2" public: auto finish_context() & -> void; -#line 5595 "reflect.h2" +#line 5607 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5601 "reflect.h2" +#line 5613 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5605 "reflect.h2" +#line 5617 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5609 "reflect.h2" +#line 5621 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5633 "reflect.h2" +#line 5645 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2253,7 +2256,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5639 "reflect.h2" +#line 5651 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2273,27 +2276,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5658 "reflect.h2" +#line 5670 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5664 "reflect.h2" +#line 5676 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5671 "reflect.h2" +#line 5683 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5688 "reflect.h2" +#line 5700 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5695 "reflect.h2" +#line 5707 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5708 "reflect.h2" +#line 5720 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2301,19 +2304,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5720 "reflect.h2" +#line 5732 "reflect.h2" }; -#line 5723 "reflect.h2" +#line 5735 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5729 "reflect.h2" +#line 5741 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5733 "reflect.h2" +#line 5745 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2321,7 +2324,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5738 "reflect.h2" +#line 5750 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2329,17 +2332,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5746 "reflect.h2" +#line 5758 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5757 "reflect.h2" +#line 5769 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5765 "reflect.h2" +#line 5777 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2347,7 +2350,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5768 "reflect.h2" +#line 5780 "reflect.h2" }; // Regex syntax: a @@ -2355,34 +2358,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5776 "reflect.h2" +#line 5788 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5785 "reflect.h2" +#line 5797 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5791 "reflect.h2" +#line 5803 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5795 "reflect.h2" +#line 5807 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5818 "reflect.h2" +#line 5830 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5839 "reflect.h2" +#line 5851 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5857 "reflect.h2" +#line 5869 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5872 "reflect.h2" +#line 5884 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5878 "reflect.h2" +#line 5890 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2390,33 +2393,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5882 "reflect.h2" +#line 5894 "reflect.h2" }; -#line 5885 "reflect.h2" +#line 5897 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5891 "reflect.h2" +#line 5903 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5903 "reflect.h2" +#line 5915 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6029 "reflect.h2" +#line 6041 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6038 "reflect.h2" +#line 6050 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6043 "reflect.h2" +#line 6055 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2424,20 +2427,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6050 "reflect.h2" +#line 6062 "reflect.h2" }; -#line 6053 "reflect.h2" +#line 6065 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6094 "reflect.h2" +#line 6106 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6105 "reflect.h2" +#line 6117 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2447,20 +2450,20 @@ class class_token class group_ref_token : public regex_token { -#line 6115 "reflect.h2" +#line 6127 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6127 "reflect.h2" +#line 6139 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6228 "reflect.h2" +#line 6240 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6232 "reflect.h2" +#line 6244 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2468,10 +2471,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6235 "reflect.h2" +#line 6247 "reflect.h2" }; -#line 6238 "reflect.h2" +#line 6250 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2485,29 +2488,29 @@ class group_ref_token class group_token : public regex_token { -#line 6252 "reflect.h2" +#line 6264 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6274 "reflect.h2" +#line 6286 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6288 "reflect.h2" +#line 6300 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6447 "reflect.h2" +#line 6459 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6455 "reflect.h2" +#line 6467 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6473 "reflect.h2" +#line 6485 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6504 "reflect.h2" +#line 6516 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2516,25 +2519,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6511 "reflect.h2" +#line 6523 "reflect.h2" }; -#line 6514 "reflect.h2" +#line 6526 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6555 "reflect.h2" +#line 6567 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6575 "reflect.h2" +#line 6587 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6591 "reflect.h2" +#line 6603 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2542,20 +2545,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6599 "reflect.h2" +#line 6611 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6608 "reflect.h2" +#line 6620 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6619 "reflect.h2" +#line 6631 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6626 "reflect.h2" +#line 6638 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2563,26 +2566,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6629 "reflect.h2" +#line 6641 "reflect.h2" }; -#line 6632 "reflect.h2" +#line 6644 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6660 "reflect.h2" +#line 6672 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6688 "reflect.h2" +#line 6700 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6694 "reflect.h2" +#line 6706 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2592,22 +2595,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6774 "reflect.h2" +#line 6786 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6786 "reflect.h2" +#line 6798 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6799 "reflect.h2" +#line 6811 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6818 "reflect.h2" +#line 6830 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6828 "reflect.h2" +#line 6840 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6839 "reflect.h2" +#line 6851 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2615,16 +2618,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6842 "reflect.h2" +#line 6854 "reflect.h2" }; -#line 6845 "reflect.h2" +#line 6857 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6851 "reflect.h2" +#line 6863 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2633,7 +2636,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6881 "reflect.h2" +#line 6893 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2642,14 +2645,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6903 "reflect.h2" +#line 6915 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6925 "reflect.h2" +#line 6937 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2670,24 +2673,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6948 "reflect.h2" +#line 6960 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6983 "reflect.h2" +#line 6995 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 6997 "reflect.h2" +#line 7009 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7009 "reflect.h2" +#line 7021 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7064 "reflect.h2" +#line 7076 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2698,7 +2701,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7190 "reflect.h2" +#line 7202 "reflect.h2" } } @@ -7210,27 +7213,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 3926 "reflect.h2" + // TODO: Have the proper type declaration here. +#line 3921 "reflect.h2" + [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ + + // TODO: Add type to required generation for AD. + + return type; // Use the same type for now. + } + +#line 3934 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3928 "reflect.h2" +#line 3936 "reflect.h2" } -#line 3926 "reflect.h2" +#line 3934 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3928 "reflect.h2" +#line 3936 "reflect.h2" } -#line 3930 "reflect.h2" +#line 3938 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 3945 "reflect.h2" +#line 3953 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7238,10 +7250,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_ } , declare_d{ declare_ }{ -#line 3950 "reflect.h2" +#line 3958 "reflect.h2" } -#line 3952 "reflect.h2" +#line 3960 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7251,7 +7263,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 3961 "reflect.h2" +#line 3969 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7290,7 +7302,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 3999 "reflect.h2" +#line 4007 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7306,62 +7318,62 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return true; } -#line 4014 "reflect.h2" +#line 4022 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4018 "reflect.h2" +#line 4026 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4022 "reflect.h2" +#line 4030 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4026 "reflect.h2" +#line 4034 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4030 "reflect.h2" +#line 4038 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4034 "reflect.h2" +#line 4042 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4038 "reflect.h2" +#line 4046 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4042 "reflect.h2" +#line 4050 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4046 "reflect.h2" +#line 4054 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4050 "reflect.h2" +#line 4058 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4054 "reflect.h2" +#line 4062 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4058 "reflect.h2" +#line 4066 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7388,7 +7400,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += cpp2::move(fwd) + cpp2::move(primal); } -#line 4084 "reflect.h2" +#line 4092 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7415,7 +7427,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4111 "reflect.h2" +#line 4119 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; @@ -7433,18 +7445,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4128 "reflect.h2" +#line 4136 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4132 "reflect.h2" +#line 4140 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); } -#line 4137 "reflect.h2" +#line 4145 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7490,7 +7502,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // TODO: Add function to list of functions/objects for differentiation. } -#line 4182 "reflect.h2" +#line 4190 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7512,46 +7524,54 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}}} } -#line 4212 "reflect.h2" +#line 4220 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4215 "reflect.h2" +#line 4223 "reflect.h2" } -#line 4217 "reflect.h2" +#line 4225 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ - CPP2_UFCS(error)(decl, "AD: Do not know how to handle declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(decl)) + ""); + base::traverse(decl); } -#line 4222 "reflect.h2" +#line 4230 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4227 "reflect.h2" +#line 4235 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ - CPP2_UFCS(error)(o, "AD: Do not know how to handle object_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(o)) + ""); + auto lhs {CPP2_UFCS(name)(o)}; + auto type {o.type()}; + + auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type))}; + + // TODO: Get initializer as expression and handle it. + auto init {CPP2_UFCS(initializer)(o)}; + diff += "" + cpp2::to_string(lhs) + "_d : " + cpp2::to_string(ad_type) + " = " + cpp2::to_string(init) + ";\n"; + diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + " = " + cpp2::to_string(cpp2::move(init)) + ";\n"; } -#line 4232 "reflect.h2" +#line 4248 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4237 "reflect.h2" +#line 4253 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4242 "reflect.h2" +#line 4258 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4247 "reflect.h2" +#line 4263 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7559,7 +7579,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += "}\n"; } -#line 4255 "reflect.h2" +#line 4271 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7575,12 +7595,12 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4271 "reflect.h2" +#line 4287 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle iteration_statement: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 4276 "reflect.h2" +#line 4292 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7592,17 +7612,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4287 "reflect.h2" +#line 4303 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { // If this is not an assignment to a parameter or return object, skip it auto lhs_rhs {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)(expr)}; auto lhs {CPP2_UFCS(get_first_token_ignoring_this)(cpp2::move(lhs_rhs).lhs)}; - if (!(CPP2_UFCS(has_parameter_or_return_named)(mf, lhs))) - { - return ; - } auto assignment {CPP2_UFCS(as_assignment_expression)(expr)}; @@ -7625,7 +7641,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4320 "reflect.h2" +#line 4332 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7677,7 +7693,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4372 "reflect.h2" +#line 4384 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -7781,7 +7797,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4385 "reflect.h2" +#line 4397 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8146,7 +8162,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4750 "reflect.h2" +#line 4762 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8162,11 +8178,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4766 "reflect.h2" +#line 4778 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4770 "reflect.h2" +#line 4782 "reflect.h2" // mod: i // mod: m // mod: s @@ -8174,116 +8190,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4779 "reflect.h2" +#line 4791 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4788 "reflect.h2" +#line 4800 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4790 "reflect.h2" +#line 4802 "reflect.h2" } -#line 4792 "reflect.h2" +#line 4804 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4794 "reflect.h2" +#line 4806 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4800 "reflect.h2" +#line 4812 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4801 "reflect.h2" +#line 4813 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4802 "reflect.h2" +#line 4814 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4817 "reflect.h2" +#line 4829 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4820 "reflect.h2" +#line 4832 "reflect.h2" } -#line 4822 "reflect.h2" +#line 4834 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4826 "reflect.h2" +#line 4838 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4838 "reflect.h2" +#line 4850 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4841 "reflect.h2" +#line 4853 "reflect.h2" } -#line 4843 "reflect.h2" +#line 4855 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4847 "reflect.h2" +#line 4859 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4857 "reflect.h2" +#line 4869 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4859 "reflect.h2" +#line 4871 "reflect.h2" } -#line 4861 "reflect.h2" +#line 4873 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4865 "reflect.h2" +#line 4877 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4877 "reflect.h2" +#line 4889 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4880 "reflect.h2" +#line 4892 "reflect.h2" } -#line 4882 "reflect.h2" +#line 4894 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4888 "reflect.h2" +#line 4900 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4894 "reflect.h2" +#line 4906 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8292,7 +8308,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4902 "reflect.h2" +#line 4914 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8308,7 +8324,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4930 "reflect.h2" +#line 4942 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8316,14 +8332,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4938 "reflect.h2" +#line 4950 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4945 "reflect.h2" +#line 4957 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8335,15 +8351,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4957 "reflect.h2" +#line 4969 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4962 "reflect.h2" +#line 4974 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4966 "reflect.h2" +#line 4978 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8364,7 +8380,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 4992 "reflect.h2" +#line 5004 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8373,20 +8389,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5001 "reflect.h2" +#line 5013 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5007 "reflect.h2" +#line 5019 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5014 "reflect.h2" +#line 5026 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8401,16 +8417,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5044 "reflect.h2" +#line 5056 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5048 "reflect.h2" +#line 5060 "reflect.h2" } -#line 5054 "reflect.h2" +#line 5066 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8420,7 +8436,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5064 "reflect.h2" +#line 5076 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8428,17 +8444,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5071 "reflect.h2" +#line 5083 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5075 "reflect.h2" +#line 5087 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5082 "reflect.h2" +#line 5094 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8448,7 +8464,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5091 "reflect.h2" +#line 5103 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8456,24 +8472,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5098 "reflect.h2" +#line 5110 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5106 "reflect.h2" +#line 5118 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5110 "reflect.h2" +#line 5122 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5114 "reflect.h2" +#line 5126 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8485,22 +8501,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5125 "reflect.h2" +#line 5137 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5131 "reflect.h2" +#line 5143 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5135 "reflect.h2" +#line 5147 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5139 "reflect.h2" +#line 5151 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8508,7 +8524,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5146 "reflect.h2" +#line 5158 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8520,10 +8536,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5159 "reflect.h2" +#line 5171 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5162 "reflect.h2" +#line 5174 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8563,7 +8579,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5202 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8575,14 +8591,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5213 "reflect.h2" +#line 5225 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5214 "reflect.h2" +#line 5226 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5215 "reflect.h2" +#line 5227 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5217 "reflect.h2" +#line 5229 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8592,10 +8608,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5226 "reflect.h2" +#line 5238 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5228 "reflect.h2" +#line 5240 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8617,14 +8633,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5249 "reflect.h2" +#line 5261 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5250 "reflect.h2" +#line 5262 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5251 "reflect.h2" +#line 5263 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5253 "reflect.h2" +#line 5265 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8638,7 +8654,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5266 "reflect.h2" +#line 5278 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8660,7 +8676,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5287 "reflect.h2" +#line 5299 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8671,12 +8687,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5297 "reflect.h2" +#line 5309 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5298 "reflect.h2" +#line 5310 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5303 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8731,7 +8747,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5357 "reflect.h2" +#line 5369 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8771,7 +8787,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5396 "reflect.h2" +#line 5408 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8787,21 +8803,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5413 "reflect.h2" +#line 5425 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5414 "reflect.h2" +#line 5426 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5415 "reflect.h2" +#line 5427 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5417 "reflect.h2" +#line 5429 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5432 "reflect.h2" +#line 5444 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8809,7 +8825,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5439 "reflect.h2" +#line 5451 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8819,22 +8835,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5457 "reflect.h2" +#line 5469 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5462 "reflect.h2" +#line 5474 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5468 "reflect.h2" +#line 5480 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5474 "reflect.h2" +#line 5486 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8843,7 +8859,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5482 "reflect.h2" +#line 5494 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8855,7 +8871,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5493 "reflect.h2" +#line 5505 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8863,7 +8879,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5500 "reflect.h2" +#line 5512 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8884,7 +8900,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5521 "reflect.h2" +#line 5533 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8894,7 +8910,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5531 "reflect.h2" +#line 5543 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8917,33 +8933,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5555 "reflect.h2" +#line 5567 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5561 "reflect.h2" +#line 5573 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5565 "reflect.h2" +#line 5577 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5571 "reflect.h2" +#line 5583 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5579 "reflect.h2" +#line 5591 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8952,7 +8968,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5587 "reflect.h2" +#line 5599 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8961,22 +8977,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5597 "reflect.h2" +#line 5609 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5601 "reflect.h2" +#line 5613 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5605 "reflect.h2" +#line 5617 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5609 "reflect.h2" +#line 5621 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9000,18 +9016,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5634 "reflect.h2" +#line 5646 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5649 "reflect.h2" +#line 5661 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5651 "reflect.h2" +#line 5663 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9022,15 +9038,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5666 "reflect.h2" +#line 5678 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5669 "reflect.h2" +#line 5681 "reflect.h2" } -#line 5671 "reflect.h2" +#line 5683 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9048,7 +9064,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5688 "reflect.h2" +#line 5700 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9056,7 +9072,7 @@ generation_function_context::generation_function_context(){} } } -#line 5695 "reflect.h2" +#line 5707 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9070,7 +9086,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5708 "reflect.h2" +#line 5720 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9086,14 +9102,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5729 "reflect.h2" +#line 5741 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5731 "reflect.h2" +#line 5743 "reflect.h2" } -#line 5733 "reflect.h2" +#line 5745 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9102,11 +9118,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5748 "reflect.h2" +#line 5760 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5750 "reflect.h2" +#line 5762 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9114,7 +9130,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5757 "reflect.h2" +#line 5769 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9123,37 +9139,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5765 "reflect.h2" +#line 5777 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5779 "reflect.h2" +#line 5791 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5783 "reflect.h2" +#line 5795 "reflect.h2" } -#line 5785 "reflect.h2" +#line 5797 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5789 "reflect.h2" +#line 5801 "reflect.h2" } -#line 5791 "reflect.h2" +#line 5803 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5795 "reflect.h2" +#line 5807 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9162,14 +9178,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5801 "reflect.h2" +#line 5813 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5806 "reflect.h2" +#line 5818 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9182,7 +9198,7 @@ size_t i{0}; } } -#line 5818 "reflect.h2" +#line 5830 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9204,7 +9220,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5839 "reflect.h2" +#line 5851 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9223,7 +9239,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5857 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9239,14 +9255,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5872 "reflect.h2" +#line 5884 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5878 "reflect.h2" +#line 5890 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9254,19 +9270,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5895 "reflect.h2" +#line 5907 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5896 "reflect.h2" +#line 5908 "reflect.h2" { -#line 5901 "reflect.h2" +#line 5913 "reflect.h2" } -#line 5904 "reflect.h2" +#line 5916 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9392,7 +9408,7 @@ size_t i{0}; ); } -#line 6029 "reflect.h2" +#line 6041 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9402,13 +9418,13 @@ size_t i{0}; ); } -#line 6038 "reflect.h2" +#line 6050 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6043 "reflect.h2" +#line 6055 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9419,12 +9435,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6055 "reflect.h2" +#line 6067 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6060 "reflect.h2" +#line 6072 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9458,7 +9474,7 @@ size_t i{0}; } -#line 6096 "reflect.h2" +#line 6108 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9467,19 +9483,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6119 "reflect.h2" +#line 6131 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6120 "reflect.h2" +#line 6132 "reflect.h2" { -#line 6125 "reflect.h2" +#line 6137 "reflect.h2" } -#line 6127 "reflect.h2" +#line 6139 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9581,19 +9597,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6228 "reflect.h2" +#line 6240 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6232 "reflect.h2" +#line 6244 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6256 "reflect.h2" +#line 6268 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9612,7 +9628,7 @@ size_t i{0}; return r; } -#line 6274 "reflect.h2" +#line 6286 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9627,7 +9643,7 @@ size_t i{0}; return r; } -#line 6288 "reflect.h2" +#line 6300 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9787,7 +9803,7 @@ size_t i{0}; } } -#line 6447 "reflect.h2" +#line 6459 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9796,7 +9812,7 @@ size_t i{0}; return r; } -#line 6455 "reflect.h2" +#line 6467 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9815,7 +9831,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6473 "reflect.h2" +#line 6485 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9847,7 +9863,7 @@ size_t i{0}; } } -#line 6504 "reflect.h2" +#line 6516 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9858,7 +9874,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6516 "reflect.h2" +#line 6528 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9897,7 +9913,7 @@ size_t i{0}; return r; } -#line 6557 "reflect.h2" +#line 6569 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9915,7 +9931,7 @@ size_t i{0}; }} } -#line 6577 "reflect.h2" +#line 6589 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9929,16 +9945,16 @@ size_t i{0}; } } -#line 6603 "reflect.h2" +#line 6615 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6606 "reflect.h2" +#line 6618 "reflect.h2" } -#line 6608 "reflect.h2" +#line 6620 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9950,7 +9966,7 @@ size_t i{0}; } } -#line 6619 "reflect.h2" +#line 6631 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9958,14 +9974,14 @@ size_t i{0}; return r; } -#line 6626 "reflect.h2" +#line 6638 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6634 "reflect.h2" +#line 6646 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9991,7 +10007,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6662 "reflect.h2" +#line 6674 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10017,11 +10033,11 @@ size_t i{0}; return r; } -#line 6699 "reflect.h2" +#line 6711 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6701 "reflect.h2" +#line 6713 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10095,7 +10111,7 @@ size_t i{0}; return nullptr; } -#line 6774 "reflect.h2" +#line 6786 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10108,7 +10124,7 @@ size_t i{0}; }} } -#line 6786 "reflect.h2" +#line 6798 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10122,7 +10138,7 @@ size_t i{0}; }} } -#line 6799 "reflect.h2" +#line 6811 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10142,7 +10158,7 @@ size_t i{0}; return r; } -#line 6818 "reflect.h2" +#line 6830 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10153,7 +10169,7 @@ size_t i{0}; return r; } -#line 6828 "reflect.h2" +#line 6840 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10165,14 +10181,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6839 "reflect.h2" +#line 6851 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6851 "reflect.h2" +#line 6863 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10196,7 +10212,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6875 "reflect.h2" +#line 6887 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10206,7 +10222,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6887 "reflect.h2" +#line 6899 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10222,7 +10238,7 @@ size_t i{0}; } } -#line 6907 "reflect.h2" +#line 6919 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10240,15 +10256,15 @@ size_t i{0}; }} } -#line 6943 "reflect.h2" +#line 6955 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6946 "reflect.h2" +#line 6958 "reflect.h2" } -#line 6948 "reflect.h2" +#line 6960 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10284,7 +10300,7 @@ size_t i{0}; return source; } -#line 6983 "reflect.h2" +#line 6995 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10300,7 +10316,7 @@ size_t i{0}; } } -#line 6999 "reflect.h2" +#line 7011 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10309,7 +10325,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10364,7 +10380,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7068 "reflect.h2" +#line 7080 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10486,7 +10502,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7190 "reflect.h2" +#line 7202 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index f2c550123..e74e1b1c0 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3916,6 +3916,14 @@ autodiff_context: type = { temporary_count += 1; return "temp_(temporary_count)$"; } + + // TODO: Have the proper type declaration here. + get_ad_type: (inout this, type: std::string) -> std::string = { + + // TODO: Add type to required generation for AD. + + return type; // Use the same type for now. + } } autodiff_handler_base: type = { @@ -4215,7 +4223,7 @@ autodiff_stmt_handler: type = { } traverse: (override inout this, decl: meta::declaration) = { - decl.error("AD: Do not know how to handle declaration: (decl.to_string())$"); + base::traverse(decl); } @@ -4225,7 +4233,15 @@ autodiff_stmt_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { - o.error("AD: Do not know how to handle object_declaration: (o.to_string())$"); + lhs := o.name(); + type := o.type(); + + ad_type := ctx*.get_ad_type(type); + + // TODO: Get initializer as expression and handle it. + init := o.initializer(); + diff += "(lhs)$_d : (ad_type)$ = (init)$;\n"; + diff += "(lhs)$ : (ad_type)$ = (init)$;\n"; } @@ -4290,10 +4306,6 @@ autodiff_stmt_handler: type = { // If this is not an assignment to a parameter or return object, skip it lhs_rhs := expr.get_lhs_rhs_if_simple_assignment(); lhs := lhs_rhs.lhs.get_first_token_ignoring_this(); - if !mf.has_parameter_or_return_named(lhs) - { - return; - } assignment := expr.as_assignment_expression(); From 0c8983d8f32a7b847c4537b3973d4972da01bf04 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 13:43:15 +0200 Subject: [PATCH 13/54] Added example for non differential variable. --- regression-tests/pure2-autodiff.cpp2 | 9 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 141 ++- .../test-results/pure2-autodiff.cpp2.output | 33 + source/reflect.h | 949 +++++++++--------- source/reflect.h2 | 43 +- 6 files changed, 664 insertions(+), 512 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index b0ec3ac91..4ecfe8379 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -88,6 +88,14 @@ ad_test: @autodiff @print type = { r = t; } + + intermediate_passive_var: (x: double, y: double) -> (r: double) = { + i: int = (); // TODO: Handle as passive when type information on call side is available. + r = x + y; + i = 2; + + _ = i; + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -119,4 +127,5 @@ main: () = { write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 23f0c0aa4..8fc9dbd23 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -16,3 +16,4 @@ diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 893766212..e22ca1f71 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -111,6 +111,11 @@ using intermediate_var_ret = double; #line 85 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; +using intermediate_passive_var_ret = double; + + +#line 92 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -188,17 +193,21 @@ struct intermediate_var_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret; +struct intermediate_passive_var_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto intermediate_passive_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 91 "pure2-autodiff.cpp2" +#line 99 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 97 "pure2-autodiff.cpp2" +#line 105 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -348,79 +357,120 @@ auto main() -> int; r.construct(cpp2::move(t)); return std::move(r.value()); } +#line 92 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ + cpp2::impl::deferred_init r; +#line 93 "pure2-autodiff.cpp2" + int i {}; // TODO: Handle as passive when type information on call side is available. + r.construct(x + y); + i = 2; + + static_cast(cpp2::move(i)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d + x_d;r = x + y + x;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d + x_d; + r = x + y + x; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d - y_d;r = x - y;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d - y_d; + r = x - y; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d - y_d - x_d;r = x - y - x;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d - y_d - x_d; + r = x - y - x; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d - x_d;r = x + y - x;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d - x_d; + r = x + y - x; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x * y_d + y * x_d;r = x * y;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x * y_d + y * x_d; + r = x * y; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d);r = cpp2::move(temp_1) * x;return { std::move(r), std::move(r_d) }; +auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); + r = cpp2::move(temp_1) * x; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y);return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; -auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y);return { std::move(r), std::move(r_d) }; +auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x));r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x);return { std::move(r), std::move(r_d) }; +auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); + r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d + y_d}; -auto temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; + + auto temp_1 {x + y}; + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; + r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d);r = x + cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; + + auto temp_1 {x * y}; + r_d = x_d + cpp2::move(temp_1_d); + r = x + cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d + y_d;r = x + y;return { std::move(r), std::move(r_d) }; + double r_d {0.0};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret{ @@ -431,22 +481,30 @@ auto temp_2 {func_diff(x, x_d, y, y_d)}; auto temp_1 {temp_2.r}; auto temp_1_d {cpp2::move(temp_2).r_d}; - r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d;r = x * cpp2::move(temp_1);return { std::move(r), std::move(r_d) }; + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; + r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret{ double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d - y_d}; -auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); + + auto temp_1 {x - y}; + r_d = cos(temp_1) * cpp2::move(temp_1_d); r = sin(cpp2::move(temp_1)); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::if_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = x_d;r = x;if (cpp2::impl::cmp_less(x,0.0)) { - r_d = y_d;r = y;} + double r_d {0.0};r_d = x_d; + r = x; + if (cpp2::impl::cmp_less(x,0.0)) { + r_d = y_d; + r = y; + } else { } return { std::move(r), std::move(r_d) }; @@ -455,32 +513,56 @@ auto temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); [[nodiscard]] auto ad_test::if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret{ double r {0.0}; double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { - r_d = y_d;r = y;} + r_d = y_d; + r = y; + } else { - r_d = x_d;r = x;} + r_d = x_d; + r = x; + } return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret{ double r {}; - double r_d {};r_d = x_d + y_d;r = x + y; - return { std::move(r), std::move(r_d) }; - } -[[nodiscard]] auto ad_test::intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret{ + double r_d {};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; } + + [[nodiscard]] auto ad_test::intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret{ double r {0.0}; double r_d {0.0}; double t_d {}; double t {}; - t_d = x_d + y_d;t = x + y;r_d = cpp2::move(t_d);r = cpp2::move(t);return { std::move(r), std::move(r_d) }; + t_d = x_d + y_d; + t = x + y; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; } -#line 93 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_passive_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_diff_ret{ + double r {0.0}; + double r_d {0.0}; +int i_d {}; + + int i {}; + r_d = x_d + y_d; + r = x + y; + i_d = { }; + i = 2; + static_cast(cpp2::move(i_d)); + static_cast(cpp2::move(i)); + return { std::move(r), std::move(r_d) }; + } + +#line 101 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 97 "pure2-autodiff.cpp2" +#line 105 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -505,6 +587,7 @@ auto main() -> int{ write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index d56b690e2..243e52879 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -185,6 +185,18 @@ ad_test:/* @autodiff @print */ type = return; } + intermediate_passive_var:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = (); + r = x + y; + i = 2; + _ = i; + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -504,6 +516,27 @@ ad_test:/* @autodiff @print */ type = r = t; return; } + + intermediate_passive_var_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + i_d: int = (); + i: int = (); + r_d = x_d + y_d; + r = x + y; + i_d = (); + i = 2; + _ = i_d; + _ = i; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 5a9d15558..a883e680b 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -114,80 +114,80 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4212 "reflect.h2" +#line 4223 "reflect.h2" class autodiff_stmt_handler; -#line 4780 "reflect.h2" +#line 4791 "reflect.h2" class expression_flags; -#line 4796 "reflect.h2" +#line 4807 "reflect.h2" class regex_token; -#line 4823 "reflect.h2" +#line 4834 "reflect.h2" class regex_token_check; -#line 4844 "reflect.h2" +#line 4855 "reflect.h2" class regex_token_code; -#line 4865 "reflect.h2" +#line 4876 "reflect.h2" class regex_token_empty; -#line 4883 "reflect.h2" +#line 4894 "reflect.h2" class regex_token_list; -#line 4935 "reflect.h2" +#line 4946 "reflect.h2" class parse_context_group_state; -#line 4996 "reflect.h2" +#line 5007 "reflect.h2" class parse_context_branch_reset_state; -#line 5039 "reflect.h2" +#line 5050 "reflect.h2" class parse_context; -#line 5440 "reflect.h2" +#line 5451 "reflect.h2" class generation_function_context; -#line 5458 "reflect.h2" +#line 5469 "reflect.h2" class generation_context; -#line 5657 "reflect.h2" +#line 5668 "reflect.h2" class alternative_token; -#line 5672 "reflect.h2" +#line 5683 "reflect.h2" class alternative_token_gen; -#line 5737 "reflect.h2" +#line 5748 "reflect.h2" class any_token; -#line 5754 "reflect.h2" +#line 5765 "reflect.h2" class atomic_group_token; -#line 5784 "reflect.h2" +#line 5795 "reflect.h2" class char_token; -#line 5899 "reflect.h2" +#line 5910 "reflect.h2" class class_token; -#line 6123 "reflect.h2" +#line 6134 "reflect.h2" class group_ref_token; -#line 6260 "reflect.h2" +#line 6271 "reflect.h2" class group_token; -#line 6607 "reflect.h2" +#line 6618 "reflect.h2" class lookahead_lookbehind_token; -#line 6702 "reflect.h2" +#line 6713 "reflect.h2" class range_token; -#line 6859 "reflect.h2" +#line 6870 "reflect.h2" class special_range_token; -#line 6945 "reflect.h2" +#line 6956 "reflect.h2" template class regex_generator; -#line 7202 "reflect.h2" +#line 7213 "reflect.h2" } } @@ -1642,125 +1642,128 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); #line 3960 "reflect.h2" + public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; + +#line 3979 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 3969 "reflect.h2" +#line 3988 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4007 "reflect.h2" +#line 4026 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 4022 "reflect.h2" +#line 4040 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4026 "reflect.h2" +#line 4044 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4030 "reflect.h2" +#line 4048 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4034 "reflect.h2" +#line 4052 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4038 "reflect.h2" +#line 4056 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4042 "reflect.h2" +#line 4060 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4046 "reflect.h2" +#line 4064 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4050 "reflect.h2" +#line 4068 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4054 "reflect.h2" +#line 4072 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4058 "reflect.h2" +#line 4076 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4062 "reflect.h2" +#line 4080 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4066 "reflect.h2" +#line 4084 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4092 "reflect.h2" +#line 4107 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4136 "reflect.h2" +#line 4150 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4140 "reflect.h2" +#line 4154 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4145 "reflect.h2" +#line 4159 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4190 "reflect.h2" +#line 4203 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4210 "reflect.h2" +#line 4221 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4216 "reflect.h2" +#line 4227 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4225 "reflect.h2" +#line 4236 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4230 "reflect.h2" +#line 4241 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4235 "reflect.h2" +#line 4246 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4248 "reflect.h2" +#line 4259 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4253 "reflect.h2" +#line 4264 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4258 "reflect.h2" +#line 4269 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4263 "reflect.h2" +#line 4274 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4271 "reflect.h2" +#line 4282 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4287 "reflect.h2" +#line 4298 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4292 "reflect.h2" +#line 4303 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4303 "reflect.h2" +#line 4314 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4330 "reflect.h2" +#line 4341 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4776 "reflect.h2" +#line 4787 "reflect.h2" using error_func = std::function x)>; -#line 4780 "reflect.h2" +#line 4791 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1795,20 +1798,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4788 "reflect.h2" +#line 4799 "reflect.h2" }; -#line 4796 "reflect.h2" +#line 4807 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4804 "reflect.h2" +#line 4815 "reflect.h2" public: explicit regex_token(); -#line 4809 "reflect.h2" +#line 4820 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1820,103 +1823,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4815 "reflect.h2" +#line 4826 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4821 "reflect.h2" +#line 4832 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4827 "reflect.h2" +#line 4838 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4834 "reflect.h2" +#line 4845 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4838 "reflect.h2" +#line 4849 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4839 "reflect.h2" +#line 4850 "reflect.h2" }; -#line 4842 "reflect.h2" +#line 4853 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4848 "reflect.h2" +#line 4859 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4855 "reflect.h2" +#line 4866 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4859 "reflect.h2" +#line 4870 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4860 "reflect.h2" +#line 4871 "reflect.h2" }; -#line 4863 "reflect.h2" +#line 4874 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4869 "reflect.h2" +#line 4880 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4873 "reflect.h2" +#line 4884 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4877 "reflect.h2" +#line 4888 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4878 "reflect.h2" +#line 4889 "reflect.h2" }; -#line 4881 "reflect.h2" +#line 4892 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4887 "reflect.h2" +#line 4898 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4894 "reflect.h2" +#line 4905 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4900 "reflect.h2" +#line 4911 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4906 "reflect.h2" +#line 4917 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4914 "reflect.h2" +#line 4925 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1924,10 +1927,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4926 "reflect.h2" +#line 4937 "reflect.h2" }; -#line 4929 "reflect.h2" +#line 4940 "reflect.h2" // // Parse and generation context. // @@ -1943,33 +1946,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4949 "reflect.h2" +#line 4960 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4956 "reflect.h2" +#line 4967 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4968 "reflect.h2" +#line 4979 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4973 "reflect.h2" +#line 4984 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4977 "reflect.h2" +#line 4988 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 4991 "reflect.h2" +#line 5002 "reflect.h2" }; -#line 4994 "reflect.h2" +#line 5005 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1982,25 +1985,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5012 "reflect.h2" +#line 5023 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5018 "reflect.h2" +#line 5029 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5025 "reflect.h2" +#line 5036 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5032 "reflect.h2" +#line 5043 "reflect.h2" }; -#line 5035 "reflect.h2" +#line 5046 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2016,7 +2019,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5051 "reflect.h2" +#line 5062 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2024,64 +2027,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5062 "reflect.h2" +#line 5073 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5075 "reflect.h2" +#line 5086 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5083 "reflect.h2" +#line 5094 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5087 "reflect.h2" +#line 5098 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5091 "reflect.h2" +#line 5102 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5103 "reflect.h2" +#line 5114 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5110 "reflect.h2" +#line 5121 "reflect.h2" public: auto next_alternative() & -> void; -#line 5116 "reflect.h2" +#line 5127 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5122 "reflect.h2" +#line 5133 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5126 "reflect.h2" +#line 5137 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5137 "reflect.h2" +#line 5148 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5141 "reflect.h2" +#line 5152 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5147 "reflect.h2" +#line 5158 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5151 "reflect.h2" +#line 5162 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5158 "reflect.h2" +#line 5169 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5169 "reflect.h2" +#line 5180 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2089,51 +2092,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5213 "reflect.h2" +#line 5224 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5225 "reflect.h2" +#line 5236 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5238 "reflect.h2" +#line 5249 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5261 "reflect.h2" +#line 5272 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5278 "reflect.h2" +#line 5289 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5299 "reflect.h2" +#line 5310 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5309 "reflect.h2" +#line 5320 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5313 "reflect.h2" +#line 5324 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5369 "reflect.h2" +#line 5380 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5408 "reflect.h2" +#line 5419 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5423 "reflect.h2" +#line 5434 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2145,10 +2148,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5434 "reflect.h2" +#line 5445 "reflect.h2" }; -#line 5437 "reflect.h2" +#line 5448 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2158,16 +2161,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5451 "reflect.h2" +#line 5462 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5454 "reflect.h2" +#line 5465 "reflect.h2" }; -#line 5457 "reflect.h2" +#line 5468 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2187,68 +2190,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5479 "reflect.h2" +#line 5490 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5485 "reflect.h2" +#line 5496 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5494 "reflect.h2" +#line 5505 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5505 "reflect.h2" +#line 5516 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5512 "reflect.h2" +#line 5523 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5532 "reflect.h2" +#line 5543 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5542 "reflect.h2" +#line 5553 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5565 "reflect.h2" +#line 5576 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5573 "reflect.h2" +#line 5584 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5577 "reflect.h2" +#line 5588 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5583 "reflect.h2" +#line 5594 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5589 "reflect.h2" +#line 5600 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5599 "reflect.h2" +#line 5610 "reflect.h2" public: auto finish_context() & -> void; -#line 5607 "reflect.h2" +#line 5618 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5613 "reflect.h2" +#line 5624 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5617 "reflect.h2" +#line 5628 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5621 "reflect.h2" +#line 5632 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5645 "reflect.h2" +#line 5656 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2256,7 +2259,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5651 "reflect.h2" +#line 5662 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2276,27 +2279,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5670 "reflect.h2" +#line 5681 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5676 "reflect.h2" +#line 5687 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5683 "reflect.h2" +#line 5694 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5700 "reflect.h2" +#line 5711 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5707 "reflect.h2" +#line 5718 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5720 "reflect.h2" +#line 5731 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2304,19 +2307,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5732 "reflect.h2" +#line 5743 "reflect.h2" }; -#line 5735 "reflect.h2" +#line 5746 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5741 "reflect.h2" +#line 5752 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5745 "reflect.h2" +#line 5756 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2324,7 +2327,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5750 "reflect.h2" +#line 5761 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2332,17 +2335,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5758 "reflect.h2" +#line 5769 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5769 "reflect.h2" +#line 5780 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5777 "reflect.h2" +#line 5788 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2350,7 +2353,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5780 "reflect.h2" +#line 5791 "reflect.h2" }; // Regex syntax: a @@ -2358,34 +2361,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5788 "reflect.h2" +#line 5799 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5797 "reflect.h2" +#line 5808 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5803 "reflect.h2" +#line 5814 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5807 "reflect.h2" +#line 5818 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5830 "reflect.h2" +#line 5841 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5851 "reflect.h2" +#line 5862 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5869 "reflect.h2" +#line 5880 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5884 "reflect.h2" +#line 5895 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5890 "reflect.h2" +#line 5901 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2393,33 +2396,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5894 "reflect.h2" +#line 5905 "reflect.h2" }; -#line 5897 "reflect.h2" +#line 5908 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5903 "reflect.h2" +#line 5914 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5915 "reflect.h2" +#line 5926 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6041 "reflect.h2" +#line 6052 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6050 "reflect.h2" +#line 6061 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6055 "reflect.h2" +#line 6066 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2427,20 +2430,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6062 "reflect.h2" +#line 6073 "reflect.h2" }; -#line 6065 "reflect.h2" +#line 6076 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6106 "reflect.h2" +#line 6117 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6117 "reflect.h2" +#line 6128 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2450,20 +2453,20 @@ class class_token class group_ref_token : public regex_token { -#line 6127 "reflect.h2" +#line 6138 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6139 "reflect.h2" +#line 6150 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6240 "reflect.h2" +#line 6251 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6244 "reflect.h2" +#line 6255 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2471,10 +2474,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6247 "reflect.h2" +#line 6258 "reflect.h2" }; -#line 6250 "reflect.h2" +#line 6261 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2488,29 +2491,29 @@ class group_ref_token class group_token : public regex_token { -#line 6264 "reflect.h2" +#line 6275 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6286 "reflect.h2" +#line 6297 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6300 "reflect.h2" +#line 6311 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6459 "reflect.h2" +#line 6470 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6467 "reflect.h2" +#line 6478 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6485 "reflect.h2" +#line 6496 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6516 "reflect.h2" +#line 6527 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2519,25 +2522,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6523 "reflect.h2" +#line 6534 "reflect.h2" }; -#line 6526 "reflect.h2" +#line 6537 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6567 "reflect.h2" +#line 6578 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6587 "reflect.h2" +#line 6598 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6603 "reflect.h2" +#line 6614 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2545,20 +2548,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6611 "reflect.h2" +#line 6622 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6620 "reflect.h2" +#line 6631 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6631 "reflect.h2" +#line 6642 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6638 "reflect.h2" +#line 6649 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2566,26 +2569,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6641 "reflect.h2" +#line 6652 "reflect.h2" }; -#line 6644 "reflect.h2" +#line 6655 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6672 "reflect.h2" +#line 6683 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6700 "reflect.h2" +#line 6711 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6706 "reflect.h2" +#line 6717 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2595,22 +2598,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6786 "reflect.h2" +#line 6797 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6798 "reflect.h2" +#line 6809 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6811 "reflect.h2" +#line 6822 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6830 "reflect.h2" +#line 6841 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6840 "reflect.h2" +#line 6851 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6851 "reflect.h2" +#line 6862 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2618,16 +2621,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6854 "reflect.h2" +#line 6865 "reflect.h2" }; -#line 6857 "reflect.h2" +#line 6868 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6863 "reflect.h2" +#line 6874 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2636,7 +2639,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6893 "reflect.h2" +#line 6904 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2645,14 +2648,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6915 "reflect.h2" +#line 6926 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6937 "reflect.h2" +#line 6948 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2673,24 +2676,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6960 "reflect.h2" +#line 6971 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 6995 "reflect.h2" +#line 7006 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7009 "reflect.h2" +#line 7020 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7021 "reflect.h2" +#line 7032 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7076 "reflect.h2" +#line 7087 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2701,7 +2704,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7202 "reflect.h2" +#line 7213 "reflect.h2" } } @@ -7254,6 +7257,26 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } #line 3960 "reflect.h2" + auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ + std::string lhs_d {lhs + "_d"}; + if (lhs == "_") { + // TODO: Maybe improve discard handling + lhs_d = lhs; + } + + auto fwd_str {"" + cpp2::to_string(cpp2::move(lhs_d)) + " " + cpp2::to_string(declare_d) + " = " + cpp2::to_string(fwd) + ";\n"}; + auto primal_str {"" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_p) + " = " + cpp2::to_string(prim) + ";\n"}; + + if (primal_first) { + diff += primal_str; + } + diff += cpp2::move(fwd_str); + if (!(primal_first)) { + diff += cpp2::move(primal_str); + } + } + +#line 3979 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7263,7 +7286,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 3969 "reflect.h2" +#line 3988 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7302,7 +7325,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4007 "reflect.h2" +#line 4026 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7312,74 +7335,73 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in auto func_diff {string_util::replace_all((*cpp2::impl::assert_not_null(cpp2::move(pos))).second, "_x_", arg)}; - diff += "" + cpp2::to_string(lhs) + "_d = " + cpp2::to_string(cpp2::move(func_diff)) + " * " + cpp2::to_string(arg) + "_d;\n"; - diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(func_name) + "(" + cpp2::to_string(arg) + ");\n"; + gen_lhs_assignment("" + cpp2::to_string(func_name) + "(" + cpp2::to_string(arg) + ")", "" + cpp2::to_string(cpp2::move(func_diff)) + " * " + cpp2::to_string(arg) + "_d"); return true; } -#line 4022 "reflect.h2" +#line 4040 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4026 "reflect.h2" +#line 4044 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4030 "reflect.h2" +#line 4048 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4034 "reflect.h2" +#line 4052 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4038 "reflect.h2" +#line 4056 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4042 "reflect.h2" +#line 4060 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4046 "reflect.h2" +#line 4064 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4050 "reflect.h2" +#line 4068 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4054 "reflect.h2" +#line 4072 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4058 "reflect.h2" +#line 4076 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4062 "reflect.h2" +#line 4080 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4066 "reflect.h2" +#line 4084 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto first {true}; - std::string fwd {"" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= "}; - std::string primal {"" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= "}; + std::string fwd {""}; + std::string primal {""}; for ( auto const& term : cpp2::move(terms) ) { if (!(first)) { auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term))}; @@ -7394,13 +7416,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in first = false; } - fwd += ";"; - primal += ";"; - - diff += cpp2::move(fwd) + cpp2::move(primal); + gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4092 "reflect.h2" +#line 4107 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7427,11 +7446,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4119 "reflect.h2" +#line 4134 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item - diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(cpp2::move(fwd)) + ";"; - diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(cpp2::move(primal)) + ";"; + gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } else { // Temporary @@ -7445,18 +7463,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4136 "reflect.h2" +#line 4150 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4140 "reflect.h2" +#line 4154 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); } -#line 4145 "reflect.h2" +#line 4159 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7496,25 +7514,22 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // Copy the return values // TODO: Look up return value name of function. - diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(ret_temp) + ".r;\n"; - diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(cpp2::move(ret_temp)) + ".r_d;\n"; + gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r_d", true); // TODO: Add function to list of functions/objects for differentiation. } -#line 4190 "reflect.h2" +#line 4203 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { - diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + "_d;"; - diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ";"; + gen_lhs_assignment(CPP2_UFCS(to_string)(primary), CPP2_UFCS(to_string)(primary) + "_d"); } else {if (CPP2_UFCS(is_expression_list)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); } else {if (CPP2_UFCS(is_literal)(primary)) { - diff += "" + cpp2::to_string(lhs) + "_d " + cpp2::to_string(declare_p) + "= ();"; - diff += "" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_d) + "= " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ";"; + gen_lhs_assignment(CPP2_UFCS(to_string)(primary), "()"); } else {if (CPP2_UFCS(is_declaration)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -7524,26 +7539,26 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}}} } -#line 4220 "reflect.h2" +#line 4231 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4223 "reflect.h2" +#line 4234 "reflect.h2" } -#line 4225 "reflect.h2" +#line 4236 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4230 "reflect.h2" +#line 4241 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4235 "reflect.h2" +#line 4246 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ auto lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7556,22 +7571,22 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + " = " + cpp2::to_string(cpp2::move(init)) + ";\n"; } -#line 4248 "reflect.h2" +#line 4259 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4253 "reflect.h2" +#line 4264 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4258 "reflect.h2" +#line 4269 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4263 "reflect.h2" +#line 4274 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7579,7 +7594,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += "}\n"; } -#line 4271 "reflect.h2" +#line 4282 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7595,12 +7610,12 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4287 "reflect.h2" +#line 4298 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle iteration_statement: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 4292 "reflect.h2" +#line 4303 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7612,7 +7627,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4303 "reflect.h2" +#line 4314 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7641,7 +7656,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4332 "reflect.h2" +#line 4343 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7693,7 +7708,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4384 "reflect.h2" +#line 4395 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -7797,7 +7812,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4397 "reflect.h2" +#line 4408 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8162,7 +8177,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4762 "reflect.h2" +#line 4773 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8178,11 +8193,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4778 "reflect.h2" +#line 4789 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4782 "reflect.h2" +#line 4793 "reflect.h2" // mod: i // mod: m // mod: s @@ -8190,116 +8205,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4791 "reflect.h2" +#line 4802 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4800 "reflect.h2" +#line 4811 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4802 "reflect.h2" +#line 4813 "reflect.h2" } -#line 4804 "reflect.h2" +#line 4815 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4806 "reflect.h2" +#line 4817 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4812 "reflect.h2" +#line 4823 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4813 "reflect.h2" +#line 4824 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4814 "reflect.h2" +#line 4825 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4829 "reflect.h2" +#line 4840 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4832 "reflect.h2" +#line 4843 "reflect.h2" } -#line 4834 "reflect.h2" +#line 4845 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4838 "reflect.h2" +#line 4849 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4850 "reflect.h2" +#line 4861 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4853 "reflect.h2" +#line 4864 "reflect.h2" } -#line 4855 "reflect.h2" +#line 4866 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4859 "reflect.h2" +#line 4870 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4869 "reflect.h2" +#line 4880 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4871 "reflect.h2" +#line 4882 "reflect.h2" } -#line 4873 "reflect.h2" +#line 4884 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4877 "reflect.h2" +#line 4888 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4889 "reflect.h2" +#line 4900 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4892 "reflect.h2" +#line 4903 "reflect.h2" } -#line 4894 "reflect.h2" +#line 4905 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4900 "reflect.h2" +#line 4911 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4906 "reflect.h2" +#line 4917 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8308,7 +8323,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4914 "reflect.h2" +#line 4925 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8324,7 +8339,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4942 "reflect.h2" +#line 4953 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8332,14 +8347,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4950 "reflect.h2" +#line 4961 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4957 "reflect.h2" +#line 4968 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8351,15 +8366,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4969 "reflect.h2" +#line 4980 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4974 "reflect.h2" +#line 4985 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4978 "reflect.h2" +#line 4989 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8380,7 +8395,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5004 "reflect.h2" +#line 5015 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8389,20 +8404,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5013 "reflect.h2" +#line 5024 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5019 "reflect.h2" +#line 5030 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5026 "reflect.h2" +#line 5037 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8417,16 +8432,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5056 "reflect.h2" +#line 5067 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5060 "reflect.h2" +#line 5071 "reflect.h2" } -#line 5066 "reflect.h2" +#line 5077 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8436,7 +8451,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5076 "reflect.h2" +#line 5087 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8444,17 +8459,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5083 "reflect.h2" +#line 5094 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5087 "reflect.h2" +#line 5098 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5094 "reflect.h2" +#line 5105 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8464,7 +8479,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5103 "reflect.h2" +#line 5114 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8472,24 +8487,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5110 "reflect.h2" +#line 5121 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5118 "reflect.h2" +#line 5129 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5122 "reflect.h2" +#line 5133 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5126 "reflect.h2" +#line 5137 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8501,22 +8516,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5137 "reflect.h2" +#line 5148 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5143 "reflect.h2" +#line 5154 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5147 "reflect.h2" +#line 5158 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5151 "reflect.h2" +#line 5162 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8524,7 +8539,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5158 "reflect.h2" +#line 5169 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8536,10 +8551,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5171 "reflect.h2" +#line 5182 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5174 "reflect.h2" +#line 5185 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8579,7 +8594,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5214 "reflect.h2" +#line 5225 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8591,14 +8606,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5225 "reflect.h2" +#line 5236 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5226 "reflect.h2" +#line 5237 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5227 "reflect.h2" +#line 5238 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5229 "reflect.h2" +#line 5240 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8608,10 +8623,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5238 "reflect.h2" +#line 5249 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5240 "reflect.h2" +#line 5251 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8633,14 +8648,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5261 "reflect.h2" +#line 5272 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5262 "reflect.h2" +#line 5273 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5263 "reflect.h2" +#line 5274 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5265 "reflect.h2" +#line 5276 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8654,7 +8669,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5278 "reflect.h2" +#line 5289 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8676,7 +8691,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5299 "reflect.h2" +#line 5310 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8687,12 +8702,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5309 "reflect.h2" +#line 5320 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5310 "reflect.h2" +#line 5321 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5315 "reflect.h2" +#line 5326 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8747,7 +8762,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5369 "reflect.h2" +#line 5380 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8787,7 +8802,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5408 "reflect.h2" +#line 5419 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8803,21 +8818,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5425 "reflect.h2" +#line 5436 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5426 "reflect.h2" +#line 5437 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5427 "reflect.h2" +#line 5438 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5429 "reflect.h2" +#line 5440 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5444 "reflect.h2" +#line 5455 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8825,7 +8840,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5451 "reflect.h2" +#line 5462 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8835,22 +8850,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5469 "reflect.h2" +#line 5480 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5474 "reflect.h2" +#line 5485 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5480 "reflect.h2" +#line 5491 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5486 "reflect.h2" +#line 5497 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8859,7 +8874,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5494 "reflect.h2" +#line 5505 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8871,7 +8886,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5505 "reflect.h2" +#line 5516 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8879,7 +8894,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5512 "reflect.h2" +#line 5523 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8900,7 +8915,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5533 "reflect.h2" +#line 5544 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8910,7 +8925,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5543 "reflect.h2" +#line 5554 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8933,33 +8948,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5567 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5573 "reflect.h2" +#line 5584 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5577 "reflect.h2" +#line 5588 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5583 "reflect.h2" +#line 5594 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5591 "reflect.h2" +#line 5602 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8968,7 +8983,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5599 "reflect.h2" +#line 5610 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8977,22 +8992,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5609 "reflect.h2" +#line 5620 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5613 "reflect.h2" +#line 5624 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5617 "reflect.h2" +#line 5628 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5621 "reflect.h2" +#line 5632 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9016,18 +9031,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5646 "reflect.h2" +#line 5657 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5661 "reflect.h2" +#line 5672 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5663 "reflect.h2" +#line 5674 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9038,15 +9053,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5678 "reflect.h2" +#line 5689 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5681 "reflect.h2" +#line 5692 "reflect.h2" } -#line 5683 "reflect.h2" +#line 5694 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9064,7 +9079,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5700 "reflect.h2" +#line 5711 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9072,7 +9087,7 @@ generation_function_context::generation_function_context(){} } } -#line 5707 "reflect.h2" +#line 5718 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9086,7 +9101,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5720 "reflect.h2" +#line 5731 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9102,14 +9117,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5741 "reflect.h2" +#line 5752 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5743 "reflect.h2" +#line 5754 "reflect.h2" } -#line 5745 "reflect.h2" +#line 5756 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9118,11 +9133,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5760 "reflect.h2" +#line 5771 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5762 "reflect.h2" +#line 5773 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9130,7 +9145,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5769 "reflect.h2" +#line 5780 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9139,37 +9154,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5777 "reflect.h2" +#line 5788 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5791 "reflect.h2" +#line 5802 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5795 "reflect.h2" +#line 5806 "reflect.h2" } -#line 5797 "reflect.h2" +#line 5808 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5801 "reflect.h2" +#line 5812 "reflect.h2" } -#line 5803 "reflect.h2" +#line 5814 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5807 "reflect.h2" +#line 5818 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9178,14 +9193,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5813 "reflect.h2" +#line 5824 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5818 "reflect.h2" +#line 5829 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9198,7 +9213,7 @@ size_t i{0}; } } -#line 5830 "reflect.h2" +#line 5841 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9220,7 +9235,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5851 "reflect.h2" +#line 5862 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9239,7 +9254,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5869 "reflect.h2" +#line 5880 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9255,14 +9270,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5884 "reflect.h2" +#line 5895 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5890 "reflect.h2" +#line 5901 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9270,19 +9285,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5907 "reflect.h2" +#line 5918 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5908 "reflect.h2" +#line 5919 "reflect.h2" { -#line 5913 "reflect.h2" +#line 5924 "reflect.h2" } -#line 5916 "reflect.h2" +#line 5927 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9408,7 +9423,7 @@ size_t i{0}; ); } -#line 6041 "reflect.h2" +#line 6052 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9418,13 +9433,13 @@ size_t i{0}; ); } -#line 6050 "reflect.h2" +#line 6061 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6055 "reflect.h2" +#line 6066 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9435,12 +9450,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6067 "reflect.h2" +#line 6078 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6072 "reflect.h2" +#line 6083 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9474,7 +9489,7 @@ size_t i{0}; } -#line 6108 "reflect.h2" +#line 6119 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9483,19 +9498,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6131 "reflect.h2" +#line 6142 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6132 "reflect.h2" +#line 6143 "reflect.h2" { -#line 6137 "reflect.h2" +#line 6148 "reflect.h2" } -#line 6139 "reflect.h2" +#line 6150 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9597,19 +9612,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6240 "reflect.h2" +#line 6251 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6244 "reflect.h2" +#line 6255 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6268 "reflect.h2" +#line 6279 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9628,7 +9643,7 @@ size_t i{0}; return r; } -#line 6286 "reflect.h2" +#line 6297 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9643,7 +9658,7 @@ size_t i{0}; return r; } -#line 6300 "reflect.h2" +#line 6311 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9803,7 +9818,7 @@ size_t i{0}; } } -#line 6459 "reflect.h2" +#line 6470 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9812,7 +9827,7 @@ size_t i{0}; return r; } -#line 6467 "reflect.h2" +#line 6478 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9831,7 +9846,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6485 "reflect.h2" +#line 6496 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9863,7 +9878,7 @@ size_t i{0}; } } -#line 6516 "reflect.h2" +#line 6527 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9874,7 +9889,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6528 "reflect.h2" +#line 6539 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9913,7 +9928,7 @@ size_t i{0}; return r; } -#line 6569 "reflect.h2" +#line 6580 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9931,7 +9946,7 @@ size_t i{0}; }} } -#line 6589 "reflect.h2" +#line 6600 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9945,16 +9960,16 @@ size_t i{0}; } } -#line 6615 "reflect.h2" +#line 6626 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6618 "reflect.h2" +#line 6629 "reflect.h2" } -#line 6620 "reflect.h2" +#line 6631 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9966,7 +9981,7 @@ size_t i{0}; } } -#line 6631 "reflect.h2" +#line 6642 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9974,14 +9989,14 @@ size_t i{0}; return r; } -#line 6638 "reflect.h2" +#line 6649 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6646 "reflect.h2" +#line 6657 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10007,7 +10022,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6674 "reflect.h2" +#line 6685 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10033,11 +10048,11 @@ size_t i{0}; return r; } -#line 6711 "reflect.h2" +#line 6722 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6713 "reflect.h2" +#line 6724 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10111,7 +10126,7 @@ size_t i{0}; return nullptr; } -#line 6786 "reflect.h2" +#line 6797 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10124,7 +10139,7 @@ size_t i{0}; }} } -#line 6798 "reflect.h2" +#line 6809 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10138,7 +10153,7 @@ size_t i{0}; }} } -#line 6811 "reflect.h2" +#line 6822 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10158,7 +10173,7 @@ size_t i{0}; return r; } -#line 6830 "reflect.h2" +#line 6841 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10169,7 +10184,7 @@ size_t i{0}; return r; } -#line 6840 "reflect.h2" +#line 6851 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10181,14 +10196,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6851 "reflect.h2" +#line 6862 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6863 "reflect.h2" +#line 6874 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10212,7 +10227,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6887 "reflect.h2" +#line 6898 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10222,7 +10237,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6899 "reflect.h2" +#line 6910 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10238,7 +10253,7 @@ size_t i{0}; } } -#line 6919 "reflect.h2" +#line 6930 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10256,15 +10271,15 @@ size_t i{0}; }} } -#line 6955 "reflect.h2" +#line 6966 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6958 "reflect.h2" +#line 6969 "reflect.h2" } -#line 6960 "reflect.h2" +#line 6971 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10300,7 +10315,7 @@ size_t i{0}; return source; } -#line 6995 "reflect.h2" +#line 7006 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10316,7 +10331,7 @@ size_t i{0}; } } -#line 7011 "reflect.h2" +#line 7022 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10325,7 +10340,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10380,7 +10395,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7080 "reflect.h2" +#line 7091 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10502,7 +10517,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7202 "reflect.h2" +#line 7213 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index e74e1b1c0..84a2412ed 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3957,6 +3957,25 @@ autodiff_expression_handler: type = { declare_d = declare_; } + gen_lhs_assignment: (inout this, prim: std::string, fwd: std::string, primal_first: bool = false) = { + lhs_d : std::string = lhs + "_d"; + if lhs == "_" { + // TODO: Maybe improve discard handling + lhs_d = lhs; + } + + fwd_str := "(lhs_d)$ (declare_d)$ = (fwd)$;\n"; + primal_str := "(lhs)$ (declare_p)$ = (prim)$;\n"; + + if primal_first { + diff += primal_str; + } + diff += fwd_str; + if !primal_first { + diff += primal_str; + } + } + handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { args : std::vector = (); for list.get_expressions() do (expr) { @@ -4013,8 +4032,7 @@ autodiff_expression_handler: type = { func_diff := string_util::replace_all(pos*.second, "_x_", arg); - diff += "(lhs)$_d = (func_diff)$ * (arg)$_d;\n"; - diff += "(lhs)$ = (func_name)$((arg)$);\n"; + gen_lhs_assignment("(func_name)$((arg)$)", "(func_diff)$ * (arg)$_d"); return true; } @@ -4067,8 +4085,8 @@ autodiff_expression_handler: type = { terms := binexpr.get_terms(); first := true; - fwd : std::string = "(lhs)$_d (declare_p)$= "; - primal: std::string = "(lhs)$ (declare_d)$= "; + fwd : std::string = ""; + primal: std::string = ""; for terms do (term) { if !first { op := term.get_op().to_string(); @@ -4083,10 +4101,7 @@ autodiff_expression_handler: type = { first = false; } - fwd += ";"; - primal += ";"; - - diff += fwd + primal; + gen_lhs_assignment(primal, fwd); } traverse: (override inout this, binexpr: meta::multiplicative_expression) = { @@ -4118,8 +4133,7 @@ autodiff_expression_handler: type = { if i + 1 == terms.ssize() { // Last item - diff += "(lhs)$_d (declare_p)$= (fwd)$;"; - diff += "(lhs)$ (declare_d)$= (primal)$;"; + gen_lhs_assignment(primal, fwd); } else { // Temporary @@ -4181,8 +4195,7 @@ autodiff_expression_handler: type = { // Copy the return values // TODO: Look up return value name of function. - diff += "(lhs)$ (declare_p)$= (ret_temp)$.r;\n"; - diff += "(lhs)$_d (declare_d)$= (ret_temp)$.r_d;\n"; + gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r_d", true); // TODO: Add function to list of functions/objects for differentiation. } @@ -4190,15 +4203,13 @@ autodiff_expression_handler: type = { traverse: (override inout this, primary: meta::primary_expression) = { if primary.is_identifier() { - diff += "(lhs)$_d (declare_p)$= (primary.to_string())$_d;"; - diff += "(lhs)$ (declare_d)$= (primary.to_string())$;"; + gen_lhs_assignment(primary.to_string(), primary.to_string() + "_d"); } else if primary.is_expression_list() { primary.error("AD: Do not know how to handle expression list inside of primary_expression: (primary.to_string())$"); } else if primary.is_literal() { - diff += "(lhs)$_d (declare_p)$= ();"; - diff += "(lhs)$ (declare_d)$= (primary.to_string())$;"; + gen_lhs_assignment(primary.to_string(), "()"); } else if primary.is_declaration() { primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); From 1d23291edf0eaac5ca93e7a0959c5098fcfcc040 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 11 Aug 2025 14:19:03 +0200 Subject: [PATCH 14/54] Added handling of while and do while loops. --- regression-tests/pure2-autodiff.cpp2 | 30 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 3 + .../test-results/pure2-autodiff.cpp | 124 ++- .../test-results/pure2-autodiff.cpp2.output | 108 +++ source/reflect.h | 806 +++++++++--------- source/reflect.h2 | 28 +- 6 files changed, 703 insertions(+), 396 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 4ecfe8379..ab695e08d 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -96,6 +96,33 @@ ad_test: @autodiff @print type = { _ = i; } + + intermediate_untyped: (x: double, y: double) -> (r: double) = { + t := 0.0; + t = x + y; + + r = t; + } + + while_loop: (x: double, y: double) -> (r: double) = { + i: int = 0; + + r = x; + while i < 2 next (i += 1) { + r = r + y ; + } + } + + do_while_loop: (x: double, y: double) -> (r: double) = { + i: int = 0; + + r = x; + do { + r = r + y ; + } + next (i += 1) + while i < 2; + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -128,4 +155,7 @@ main: () = { write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 8fc9dbd23..7890df22c 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -17,3 +17,6 @@ diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000 diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index e22ca1f71..92351463d 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -116,6 +116,21 @@ using intermediate_passive_var_ret = double; #line 92 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; +using intermediate_untyped_ret = double; + + +#line 100 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; +using while_loop_ret = double; + + +#line 107 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; +using do_while_loop_ret = double; + + +#line 116 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -197,17 +212,29 @@ struct intermediate_passive_var_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto intermediate_passive_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_diff_ret; +struct intermediate_untyped_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto intermediate_untyped_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_diff_ret; + +struct while_loop_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret; + +struct do_while_loop_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 99 "pure2-autodiff.cpp2" +#line 126 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 105 "pure2-autodiff.cpp2" +#line 132 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -368,6 +395,42 @@ auto main() -> int; static_cast(cpp2::move(i)); return std::move(r.value()); } +#line 100 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ + cpp2::impl::deferred_init r; +#line 101 "pure2-autodiff.cpp2" + auto t {0.0}; + t = x + y; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + +#line 107 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ + cpp2::impl::deferred_init r; +#line 108 "pure2-autodiff.cpp2" + int i {0}; + + r.construct(x); + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + r.value() = r.value() + y; + }return std::move(r.value()); + } + +#line 116 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ + cpp2::impl::deferred_init r; +#line 117 "pure2-autodiff.cpp2" + int i {0}; + + r.construct(x); + do { + r.value() = r.value() + y; + } while ( [&]{ + (i += 1) ; return true; }() && + cpp2::impl::cmp_less(i,2));return std::move(r.value()); + } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d; @@ -557,12 +620,60 @@ int i_d {}; return { std::move(r), std::move(r_d) }; } -#line 101 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_untyped_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_diff_ret{ + double r {0.0}; + double r_d {0.0}; +auto t_d {0.0}; + + auto t {0.0}; + t_d = x_d + y_d; + t = x + y; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret{ + double r {0.0}; + double r_d {0.0}; +int i_d {0}; + + int i {0}; + r_d = x_d; + r = x; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + r_d = r_d + y_d; + r = r + y; + } + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret{ + double r {0.0}; + double r_d {0.0}; +int i_d {0}; + + int i {0}; + r_d = x_d; + r = x; + do { + r_d = r_d + y_d; + r = r + y; + } + while ( [&]{ + (i += 1) + ; return true; }() && + cpp2::impl::cmp_less(i,2) + ); + return { std::move(r), std::move(r_d) }; + } + +#line 128 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 105 "pure2-autodiff.cpp2" +#line 132 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -588,6 +699,9 @@ auto main() -> int{ write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 243e52879..3d9427c60 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -197,6 +197,48 @@ ad_test:/* @autodiff @print */ type = return; } + intermediate_untyped:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: _ = 0.0; + t = x + y; + r = t; + return; + } + + while_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = 0; + r = x; + while i < 2 + next (i += 1) + { + r = r + y; + } + return; + } + + do_while_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = 0; + r = x; + do + { + r = r + y; + } + next (i += 1) + while i < 2; + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -537,6 +579,72 @@ ad_test:/* @autodiff @print */ type = _ = i; return; } + + intermediate_untyped_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + t_d: _ = 0.0; + t: _ = 0.0; + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + + while_loop_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + i_d: int = 0; + i: int = 0; + r_d = x_d; + r = x; + while i < 2 + next (i += 1) + { + r_d = r_d + y_d; + r = r + y; + } + return; + } + + do_while_loop_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + i_d: int = 0; + i: int = 0; + r_d = x_d; + r = x; + do + { + r_d = r_d + y_d; + r = r + y; + } + next (i += 1) + while i < 2; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index a883e680b..af4052d3b 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -117,77 +117,77 @@ class autodiff_expression_handler; #line 4223 "reflect.h2" class autodiff_stmt_handler; -#line 4791 "reflect.h2" +#line 4817 "reflect.h2" class expression_flags; -#line 4807 "reflect.h2" +#line 4833 "reflect.h2" class regex_token; -#line 4834 "reflect.h2" +#line 4860 "reflect.h2" class regex_token_check; -#line 4855 "reflect.h2" +#line 4881 "reflect.h2" class regex_token_code; -#line 4876 "reflect.h2" +#line 4902 "reflect.h2" class regex_token_empty; -#line 4894 "reflect.h2" +#line 4920 "reflect.h2" class regex_token_list; -#line 4946 "reflect.h2" +#line 4972 "reflect.h2" class parse_context_group_state; -#line 5007 "reflect.h2" +#line 5033 "reflect.h2" class parse_context_branch_reset_state; -#line 5050 "reflect.h2" +#line 5076 "reflect.h2" class parse_context; -#line 5451 "reflect.h2" +#line 5477 "reflect.h2" class generation_function_context; -#line 5469 "reflect.h2" +#line 5495 "reflect.h2" class generation_context; -#line 5668 "reflect.h2" +#line 5694 "reflect.h2" class alternative_token; -#line 5683 "reflect.h2" +#line 5709 "reflect.h2" class alternative_token_gen; -#line 5748 "reflect.h2" +#line 5774 "reflect.h2" class any_token; -#line 5765 "reflect.h2" +#line 5791 "reflect.h2" class atomic_group_token; -#line 5795 "reflect.h2" +#line 5821 "reflect.h2" class char_token; -#line 5910 "reflect.h2" +#line 5936 "reflect.h2" class class_token; -#line 6134 "reflect.h2" +#line 6160 "reflect.h2" class group_ref_token; -#line 6271 "reflect.h2" +#line 6297 "reflect.h2" class group_token; -#line 6618 "reflect.h2" +#line 6644 "reflect.h2" class lookahead_lookbehind_token; -#line 6713 "reflect.h2" +#line 6739 "reflect.h2" class range_token; -#line 6870 "reflect.h2" +#line 6896 "reflect.h2" class special_range_token; -#line 6956 "reflect.h2" +#line 6982 "reflect.h2" template class regex_generator; -#line 7213 "reflect.h2" +#line 7239 "reflect.h2" } } @@ -1746,24 +1746,24 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba #line 4298 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4303 "reflect.h2" +#line 4329 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4314 "reflect.h2" +#line 4340 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4341 "reflect.h2" +#line 4367 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4787 "reflect.h2" +#line 4813 "reflect.h2" using error_func = std::function x)>; -#line 4791 "reflect.h2" +#line 4817 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1798,20 +1798,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4799 "reflect.h2" +#line 4825 "reflect.h2" }; -#line 4807 "reflect.h2" +#line 4833 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4815 "reflect.h2" +#line 4841 "reflect.h2" public: explicit regex_token(); -#line 4820 "reflect.h2" +#line 4846 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1823,103 +1823,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4826 "reflect.h2" +#line 4852 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4832 "reflect.h2" +#line 4858 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4838 "reflect.h2" +#line 4864 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4845 "reflect.h2" +#line 4871 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4849 "reflect.h2" +#line 4875 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4850 "reflect.h2" +#line 4876 "reflect.h2" }; -#line 4853 "reflect.h2" +#line 4879 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4859 "reflect.h2" +#line 4885 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4866 "reflect.h2" +#line 4892 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4870 "reflect.h2" +#line 4896 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4871 "reflect.h2" +#line 4897 "reflect.h2" }; -#line 4874 "reflect.h2" +#line 4900 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4880 "reflect.h2" +#line 4906 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4884 "reflect.h2" +#line 4910 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4888 "reflect.h2" +#line 4914 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4889 "reflect.h2" +#line 4915 "reflect.h2" }; -#line 4892 "reflect.h2" +#line 4918 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4898 "reflect.h2" +#line 4924 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4905 "reflect.h2" +#line 4931 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4911 "reflect.h2" +#line 4937 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4917 "reflect.h2" +#line 4943 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4925 "reflect.h2" +#line 4951 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1927,10 +1927,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4937 "reflect.h2" +#line 4963 "reflect.h2" }; -#line 4940 "reflect.h2" +#line 4966 "reflect.h2" // // Parse and generation context. // @@ -1946,33 +1946,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4960 "reflect.h2" +#line 4986 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4967 "reflect.h2" +#line 4993 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4979 "reflect.h2" +#line 5005 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 4984 "reflect.h2" +#line 5010 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 4988 "reflect.h2" +#line 5014 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5002 "reflect.h2" +#line 5028 "reflect.h2" }; -#line 5005 "reflect.h2" +#line 5031 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1985,25 +1985,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5023 "reflect.h2" +#line 5049 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5029 "reflect.h2" +#line 5055 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5036 "reflect.h2" +#line 5062 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5043 "reflect.h2" +#line 5069 "reflect.h2" }; -#line 5046 "reflect.h2" +#line 5072 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2019,7 +2019,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5062 "reflect.h2" +#line 5088 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2027,64 +2027,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5073 "reflect.h2" +#line 5099 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5086 "reflect.h2" +#line 5112 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5094 "reflect.h2" +#line 5120 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5098 "reflect.h2" +#line 5124 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5102 "reflect.h2" +#line 5128 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5114 "reflect.h2" +#line 5140 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5121 "reflect.h2" +#line 5147 "reflect.h2" public: auto next_alternative() & -> void; -#line 5127 "reflect.h2" +#line 5153 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5133 "reflect.h2" +#line 5159 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5137 "reflect.h2" +#line 5163 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5148 "reflect.h2" +#line 5174 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5152 "reflect.h2" +#line 5178 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5158 "reflect.h2" +#line 5184 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5162 "reflect.h2" +#line 5188 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5169 "reflect.h2" +#line 5195 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5180 "reflect.h2" +#line 5206 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2092,51 +2092,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5224 "reflect.h2" +#line 5250 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5236 "reflect.h2" +#line 5262 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5249 "reflect.h2" +#line 5275 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5272 "reflect.h2" +#line 5298 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5289 "reflect.h2" +#line 5315 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5310 "reflect.h2" +#line 5336 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5320 "reflect.h2" +#line 5346 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5324 "reflect.h2" +#line 5350 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5380 "reflect.h2" +#line 5406 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5419 "reflect.h2" +#line 5445 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5434 "reflect.h2" +#line 5460 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2148,10 +2148,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5445 "reflect.h2" +#line 5471 "reflect.h2" }; -#line 5448 "reflect.h2" +#line 5474 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2161,16 +2161,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5462 "reflect.h2" +#line 5488 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5465 "reflect.h2" +#line 5491 "reflect.h2" }; -#line 5468 "reflect.h2" +#line 5494 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2190,68 +2190,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5490 "reflect.h2" +#line 5516 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5496 "reflect.h2" +#line 5522 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5505 "reflect.h2" +#line 5531 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5516 "reflect.h2" +#line 5542 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5523 "reflect.h2" +#line 5549 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5543 "reflect.h2" +#line 5569 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5553 "reflect.h2" +#line 5579 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5576 "reflect.h2" +#line 5602 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5584 "reflect.h2" +#line 5610 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5588 "reflect.h2" +#line 5614 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5594 "reflect.h2" +#line 5620 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5600 "reflect.h2" +#line 5626 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5610 "reflect.h2" +#line 5636 "reflect.h2" public: auto finish_context() & -> void; -#line 5618 "reflect.h2" +#line 5644 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5624 "reflect.h2" +#line 5650 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5628 "reflect.h2" +#line 5654 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5632 "reflect.h2" +#line 5658 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5656 "reflect.h2" +#line 5682 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2259,7 +2259,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5662 "reflect.h2" +#line 5688 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2279,27 +2279,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5681 "reflect.h2" +#line 5707 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5687 "reflect.h2" +#line 5713 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5694 "reflect.h2" +#line 5720 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5711 "reflect.h2" +#line 5737 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5718 "reflect.h2" +#line 5744 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5731 "reflect.h2" +#line 5757 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2307,19 +2307,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5743 "reflect.h2" +#line 5769 "reflect.h2" }; -#line 5746 "reflect.h2" +#line 5772 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5752 "reflect.h2" +#line 5778 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5756 "reflect.h2" +#line 5782 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2327,7 +2327,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5761 "reflect.h2" +#line 5787 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2335,17 +2335,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5769 "reflect.h2" +#line 5795 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5780 "reflect.h2" +#line 5806 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5788 "reflect.h2" +#line 5814 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2353,7 +2353,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5791 "reflect.h2" +#line 5817 "reflect.h2" }; // Regex syntax: a @@ -2361,34 +2361,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5799 "reflect.h2" +#line 5825 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5808 "reflect.h2" +#line 5834 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5814 "reflect.h2" +#line 5840 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5818 "reflect.h2" +#line 5844 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5841 "reflect.h2" +#line 5867 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5862 "reflect.h2" +#line 5888 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5880 "reflect.h2" +#line 5906 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5895 "reflect.h2" +#line 5921 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5901 "reflect.h2" +#line 5927 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2396,33 +2396,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5905 "reflect.h2" +#line 5931 "reflect.h2" }; -#line 5908 "reflect.h2" +#line 5934 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5914 "reflect.h2" +#line 5940 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5926 "reflect.h2" +#line 5952 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6052 "reflect.h2" +#line 6078 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6061 "reflect.h2" +#line 6087 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6066 "reflect.h2" +#line 6092 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2430,20 +2430,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6073 "reflect.h2" +#line 6099 "reflect.h2" }; -#line 6076 "reflect.h2" +#line 6102 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6117 "reflect.h2" +#line 6143 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6128 "reflect.h2" +#line 6154 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2453,20 +2453,20 @@ class class_token class group_ref_token : public regex_token { -#line 6138 "reflect.h2" +#line 6164 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6150 "reflect.h2" +#line 6176 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6251 "reflect.h2" +#line 6277 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6255 "reflect.h2" +#line 6281 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2474,10 +2474,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6258 "reflect.h2" +#line 6284 "reflect.h2" }; -#line 6261 "reflect.h2" +#line 6287 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2491,29 +2491,29 @@ class group_ref_token class group_token : public regex_token { -#line 6275 "reflect.h2" +#line 6301 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6297 "reflect.h2" +#line 6323 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6311 "reflect.h2" +#line 6337 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6470 "reflect.h2" +#line 6496 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6478 "reflect.h2" +#line 6504 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6496 "reflect.h2" +#line 6522 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6527 "reflect.h2" +#line 6553 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2522,25 +2522,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6534 "reflect.h2" +#line 6560 "reflect.h2" }; -#line 6537 "reflect.h2" +#line 6563 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6578 "reflect.h2" +#line 6604 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6598 "reflect.h2" +#line 6624 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6614 "reflect.h2" +#line 6640 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2548,20 +2548,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6622 "reflect.h2" +#line 6648 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6631 "reflect.h2" +#line 6657 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6642 "reflect.h2" +#line 6668 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6649 "reflect.h2" +#line 6675 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2569,26 +2569,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6652 "reflect.h2" +#line 6678 "reflect.h2" }; -#line 6655 "reflect.h2" +#line 6681 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6683 "reflect.h2" +#line 6709 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6711 "reflect.h2" +#line 6737 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6717 "reflect.h2" +#line 6743 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2598,22 +2598,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6797 "reflect.h2" +#line 6823 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6809 "reflect.h2" +#line 6835 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6822 "reflect.h2" +#line 6848 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6841 "reflect.h2" +#line 6867 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6851 "reflect.h2" +#line 6877 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6862 "reflect.h2" +#line 6888 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2621,16 +2621,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6865 "reflect.h2" +#line 6891 "reflect.h2" }; -#line 6868 "reflect.h2" +#line 6894 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6874 "reflect.h2" +#line 6900 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2639,7 +2639,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6904 "reflect.h2" +#line 6930 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2648,14 +2648,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6926 "reflect.h2" +#line 6952 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6948 "reflect.h2" +#line 6974 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2676,24 +2676,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6971 "reflect.h2" +#line 6997 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7006 "reflect.h2" +#line 7032 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7020 "reflect.h2" +#line 7046 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7032 "reflect.h2" +#line 7058 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7087 "reflect.h2" +#line 7113 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2704,7 +2704,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7213 "reflect.h2" +#line 7239 "reflect.h2" } } @@ -7612,10 +7612,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 4298 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - CPP2_UFCS(error)(stmt, "AD: Do not know how to handle iteration_statement: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); + if (CPP2_UFCS(is_while)(stmt)) { + // TODO: Assumption is here that nothing is in the condition + diff += "while " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_do_while_condition)(stmt))) + " "; + if (CPP2_UFCS(has_next)(stmt)) { + // TODO: Assumption is here that nothing is in the next expression + diff += "next " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + " "; + } + + pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); + } + else {if (CPP2_UFCS(is_do)(stmt)) { + // TODO: Assumption is here that nothing is in the condition + + diff += "do "; + pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); + + if (CPP2_UFCS(has_next)(stmt)) { + // TODO: Assumption is here that nothing is in the next expression + diff += "next " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + " "; + } + diff += "while " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_do_while_condition)(stmt))) + ";"; + } + else { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_for)(stmt)) ) { cpp2::cpp2_default.report_violation(""); } + + CPP2_UFCS(error)(stmt, "AD: Do not know how to handle for loops: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); + }} } -#line 4303 "reflect.h2" +#line 4329 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7627,7 +7653,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4314 "reflect.h2" +#line 4340 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7656,7 +7682,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4343 "reflect.h2" +#line 4369 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7708,7 +7734,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4395 "reflect.h2" +#line 4421 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -7812,7 +7838,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4408 "reflect.h2" +#line 4434 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8177,7 +8203,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4773 "reflect.h2" +#line 4799 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8193,11 +8219,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4789 "reflect.h2" +#line 4815 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4793 "reflect.h2" +#line 4819 "reflect.h2" // mod: i // mod: m // mod: s @@ -8205,116 +8231,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4802 "reflect.h2" +#line 4828 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4811 "reflect.h2" +#line 4837 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4813 "reflect.h2" +#line 4839 "reflect.h2" } -#line 4815 "reflect.h2" +#line 4841 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4817 "reflect.h2" +#line 4843 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4823 "reflect.h2" +#line 4849 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4824 "reflect.h2" +#line 4850 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4825 "reflect.h2" +#line 4851 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4840 "reflect.h2" +#line 4866 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4843 "reflect.h2" +#line 4869 "reflect.h2" } -#line 4845 "reflect.h2" +#line 4871 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4849 "reflect.h2" +#line 4875 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4861 "reflect.h2" +#line 4887 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4864 "reflect.h2" +#line 4890 "reflect.h2" } -#line 4866 "reflect.h2" +#line 4892 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4870 "reflect.h2" +#line 4896 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4880 "reflect.h2" +#line 4906 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4882 "reflect.h2" +#line 4908 "reflect.h2" } -#line 4884 "reflect.h2" +#line 4910 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4888 "reflect.h2" +#line 4914 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4900 "reflect.h2" +#line 4926 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4903 "reflect.h2" +#line 4929 "reflect.h2" } -#line 4905 "reflect.h2" +#line 4931 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4911 "reflect.h2" +#line 4937 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4917 "reflect.h2" +#line 4943 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8323,7 +8349,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4925 "reflect.h2" +#line 4951 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8339,7 +8365,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4953 "reflect.h2" +#line 4979 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8347,14 +8373,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4961 "reflect.h2" +#line 4987 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4968 "reflect.h2" +#line 4994 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8366,15 +8392,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4980 "reflect.h2" +#line 5006 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 4985 "reflect.h2" +#line 5011 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 4989 "reflect.h2" +#line 5015 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8395,7 +8421,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5015 "reflect.h2" +#line 5041 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8404,20 +8430,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5024 "reflect.h2" +#line 5050 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5030 "reflect.h2" +#line 5056 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5037 "reflect.h2" +#line 5063 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8432,16 +8458,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5067 "reflect.h2" +#line 5093 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5071 "reflect.h2" +#line 5097 "reflect.h2" } -#line 5077 "reflect.h2" +#line 5103 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8451,7 +8477,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5087 "reflect.h2" +#line 5113 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8459,17 +8485,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5094 "reflect.h2" +#line 5120 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5098 "reflect.h2" +#line 5124 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5105 "reflect.h2" +#line 5131 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8479,7 +8505,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5114 "reflect.h2" +#line 5140 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8487,24 +8513,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5121 "reflect.h2" +#line 5147 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5129 "reflect.h2" +#line 5155 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5133 "reflect.h2" +#line 5159 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5137 "reflect.h2" +#line 5163 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8516,22 +8542,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5148 "reflect.h2" +#line 5174 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5154 "reflect.h2" +#line 5180 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5158 "reflect.h2" +#line 5184 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5162 "reflect.h2" +#line 5188 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8539,7 +8565,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5169 "reflect.h2" +#line 5195 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8551,10 +8577,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5182 "reflect.h2" +#line 5208 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5185 "reflect.h2" +#line 5211 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8594,7 +8620,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5225 "reflect.h2" +#line 5251 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8606,14 +8632,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5236 "reflect.h2" +#line 5262 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5237 "reflect.h2" +#line 5263 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5238 "reflect.h2" +#line 5264 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5240 "reflect.h2" +#line 5266 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8623,10 +8649,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5249 "reflect.h2" +#line 5275 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5251 "reflect.h2" +#line 5277 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8648,14 +8674,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5272 "reflect.h2" +#line 5298 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5273 "reflect.h2" +#line 5299 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5274 "reflect.h2" +#line 5300 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5276 "reflect.h2" +#line 5302 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8669,7 +8695,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5289 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8691,7 +8717,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5310 "reflect.h2" +#line 5336 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8702,12 +8728,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5320 "reflect.h2" +#line 5346 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5321 "reflect.h2" +#line 5347 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5326 "reflect.h2" +#line 5352 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8762,7 +8788,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5380 "reflect.h2" +#line 5406 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8802,7 +8828,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5419 "reflect.h2" +#line 5445 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8818,21 +8844,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5436 "reflect.h2" +#line 5462 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5437 "reflect.h2" +#line 5463 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5438 "reflect.h2" +#line 5464 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5440 "reflect.h2" +#line 5466 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5455 "reflect.h2" +#line 5481 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8840,7 +8866,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5462 "reflect.h2" +#line 5488 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8850,22 +8876,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5480 "reflect.h2" +#line 5506 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5485 "reflect.h2" +#line 5511 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5491 "reflect.h2" +#line 5517 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5497 "reflect.h2" +#line 5523 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8874,7 +8900,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5505 "reflect.h2" +#line 5531 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8886,7 +8912,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5516 "reflect.h2" +#line 5542 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8894,7 +8920,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5523 "reflect.h2" +#line 5549 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8915,7 +8941,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5544 "reflect.h2" +#line 5570 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8925,7 +8951,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5554 "reflect.h2" +#line 5580 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8948,33 +8974,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5578 "reflect.h2" +#line 5604 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5584 "reflect.h2" +#line 5610 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5588 "reflect.h2" +#line 5614 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5594 "reflect.h2" +#line 5620 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5602 "reflect.h2" +#line 5628 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -8983,7 +9009,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5610 "reflect.h2" +#line 5636 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -8992,22 +9018,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5620 "reflect.h2" +#line 5646 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5624 "reflect.h2" +#line 5650 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5628 "reflect.h2" +#line 5654 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5632 "reflect.h2" +#line 5658 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9031,18 +9057,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5657 "reflect.h2" +#line 5683 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5672 "reflect.h2" +#line 5698 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5674 "reflect.h2" +#line 5700 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9053,15 +9079,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5689 "reflect.h2" +#line 5715 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5692 "reflect.h2" +#line 5718 "reflect.h2" } -#line 5694 "reflect.h2" +#line 5720 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9079,7 +9105,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5711 "reflect.h2" +#line 5737 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9087,7 +9113,7 @@ generation_function_context::generation_function_context(){} } } -#line 5718 "reflect.h2" +#line 5744 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9101,7 +9127,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5731 "reflect.h2" +#line 5757 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9117,14 +9143,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5752 "reflect.h2" +#line 5778 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5754 "reflect.h2" +#line 5780 "reflect.h2" } -#line 5756 "reflect.h2" +#line 5782 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9133,11 +9159,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5771 "reflect.h2" +#line 5797 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5773 "reflect.h2" +#line 5799 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9145,7 +9171,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5780 "reflect.h2" +#line 5806 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9154,37 +9180,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5788 "reflect.h2" +#line 5814 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5802 "reflect.h2" +#line 5828 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5806 "reflect.h2" +#line 5832 "reflect.h2" } -#line 5808 "reflect.h2" +#line 5834 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5812 "reflect.h2" +#line 5838 "reflect.h2" } -#line 5814 "reflect.h2" +#line 5840 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5818 "reflect.h2" +#line 5844 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9193,14 +9219,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5824 "reflect.h2" +#line 5850 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5829 "reflect.h2" +#line 5855 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9213,7 +9239,7 @@ size_t i{0}; } } -#line 5841 "reflect.h2" +#line 5867 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9235,7 +9261,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5862 "reflect.h2" +#line 5888 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9254,7 +9280,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5880 "reflect.h2" +#line 5906 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9270,14 +9296,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5895 "reflect.h2" +#line 5921 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5901 "reflect.h2" +#line 5927 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9285,19 +9311,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5918 "reflect.h2" +#line 5944 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5919 "reflect.h2" +#line 5945 "reflect.h2" { -#line 5924 "reflect.h2" +#line 5950 "reflect.h2" } -#line 5927 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9423,7 +9449,7 @@ size_t i{0}; ); } -#line 6052 "reflect.h2" +#line 6078 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9433,13 +9459,13 @@ size_t i{0}; ); } -#line 6061 "reflect.h2" +#line 6087 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6066 "reflect.h2" +#line 6092 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9450,12 +9476,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6078 "reflect.h2" +#line 6104 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6083 "reflect.h2" +#line 6109 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9489,7 +9515,7 @@ size_t i{0}; } -#line 6119 "reflect.h2" +#line 6145 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9498,19 +9524,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6142 "reflect.h2" +#line 6168 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6143 "reflect.h2" +#line 6169 "reflect.h2" { -#line 6148 "reflect.h2" +#line 6174 "reflect.h2" } -#line 6150 "reflect.h2" +#line 6176 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9612,19 +9638,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6251 "reflect.h2" +#line 6277 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6255 "reflect.h2" +#line 6281 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6279 "reflect.h2" +#line 6305 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9643,7 +9669,7 @@ size_t i{0}; return r; } -#line 6297 "reflect.h2" +#line 6323 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9658,7 +9684,7 @@ size_t i{0}; return r; } -#line 6311 "reflect.h2" +#line 6337 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9818,7 +9844,7 @@ size_t i{0}; } } -#line 6470 "reflect.h2" +#line 6496 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9827,7 +9853,7 @@ size_t i{0}; return r; } -#line 6478 "reflect.h2" +#line 6504 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9846,7 +9872,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6496 "reflect.h2" +#line 6522 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9878,7 +9904,7 @@ size_t i{0}; } } -#line 6527 "reflect.h2" +#line 6553 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9889,7 +9915,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6539 "reflect.h2" +#line 6565 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9928,7 +9954,7 @@ size_t i{0}; return r; } -#line 6580 "reflect.h2" +#line 6606 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9946,7 +9972,7 @@ size_t i{0}; }} } -#line 6600 "reflect.h2" +#line 6626 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9960,16 +9986,16 @@ size_t i{0}; } } -#line 6626 "reflect.h2" +#line 6652 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6629 "reflect.h2" +#line 6655 "reflect.h2" } -#line 6631 "reflect.h2" +#line 6657 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -9981,7 +10007,7 @@ size_t i{0}; } } -#line 6642 "reflect.h2" +#line 6668 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -9989,14 +10015,14 @@ size_t i{0}; return r; } -#line 6649 "reflect.h2" +#line 6675 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6657 "reflect.h2" +#line 6683 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10022,7 +10048,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6685 "reflect.h2" +#line 6711 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10048,11 +10074,11 @@ size_t i{0}; return r; } -#line 6722 "reflect.h2" +#line 6748 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6724 "reflect.h2" +#line 6750 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10126,7 +10152,7 @@ size_t i{0}; return nullptr; } -#line 6797 "reflect.h2" +#line 6823 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10139,7 +10165,7 @@ size_t i{0}; }} } -#line 6809 "reflect.h2" +#line 6835 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10153,7 +10179,7 @@ size_t i{0}; }} } -#line 6822 "reflect.h2" +#line 6848 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10173,7 +10199,7 @@ size_t i{0}; return r; } -#line 6841 "reflect.h2" +#line 6867 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10184,7 +10210,7 @@ size_t i{0}; return r; } -#line 6851 "reflect.h2" +#line 6877 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10196,14 +10222,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6862 "reflect.h2" +#line 6888 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6874 "reflect.h2" +#line 6900 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10227,7 +10253,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6898 "reflect.h2" +#line 6924 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10237,7 +10263,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6910 "reflect.h2" +#line 6936 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10253,7 +10279,7 @@ size_t i{0}; } } -#line 6930 "reflect.h2" +#line 6956 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10271,15 +10297,15 @@ size_t i{0}; }} } -#line 6966 "reflect.h2" +#line 6992 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6969 "reflect.h2" +#line 6995 "reflect.h2" } -#line 6971 "reflect.h2" +#line 6997 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10315,7 +10341,7 @@ size_t i{0}; return source; } -#line 7006 "reflect.h2" +#line 7032 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10331,7 +10357,7 @@ size_t i{0}; } } -#line 7022 "reflect.h2" +#line 7048 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10340,7 +10366,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10395,7 +10421,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7091 "reflect.h2" +#line 7117 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10517,7 +10543,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7213 "reflect.h2" +#line 7239 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 84a2412ed..c87f8a4ba 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4296,7 +4296,33 @@ autodiff_stmt_handler: type = { traverse: (override inout this, stmt: meta::iteration_statement) = { - stmt.error("AD: Do not know how to handle iteration_statement: (stmt.to_string())$"); + if stmt.is_while() { + // TODO: Assumption is here that nothing is in the condition + diff += "while (stmt.get_do_while_condition().to_string())$ "; + if stmt.has_next() { + // TODO: Assumption is here that nothing is in the next expression + diff += "next (stmt.get_next_expression().to_string())$ "; + } + + pre_traverse(stmt.get_do_while_body()); + } + else if stmt.is_do() { + // TODO: Assumption is here that nothing is in the condition + + diff += "do "; + pre_traverse(stmt.get_do_while_body()); + + if stmt.has_next() { + // TODO: Assumption is here that nothing is in the next expression + diff += "next (stmt.get_next_expression().to_string())$ "; + } + diff += "while (stmt.get_do_while_condition().to_string())$;"; + } + else { + assert(stmt.is_for()); + + stmt.error("AD: Do not know how to handle for loops: (stmt.to_string())$"); + } } From be60ab22f532a25ab3d1d3d567cb04e197b6c7aa Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 11:28:06 +0200 Subject: [PATCH 15/54] Handling of for loops and added special functions. --- regression-tests/pure2-autodiff.cpp2 | 15 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 65 +- .../test-results/pure2-autodiff.cpp2.output | 49 + source/reflect.h | 1346 +++++++++++------ source/reflect.h2 | 251 ++- 6 files changed, 1237 insertions(+), 490 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index ab695e08d..529a36787 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -123,6 +123,20 @@ ad_test: @autodiff @print type = { next (i += 1) while i < 2; } + + for_loop: (x: double, y: double) -> (r: double) = { + v: std::vector = (); + + v.push_back(x); + v.push_back(y); + + r = 0.0; + for v + do (t) + { + r = r + t; + } + } } write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { @@ -158,4 +172,5 @@ main: () = { write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 7890df22c..77f4ca3a7 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -20,3 +20,4 @@ diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 92351463d..464e49c83 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -131,6 +131,11 @@ using do_while_loop_ret = double; #line 116 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; +using for_loop_ret = double; + + +#line 127 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -224,17 +229,21 @@ struct do_while_loop_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret; +struct for_loop_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto for_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_diff_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 126 "pure2-autodiff.cpp2" +#line 140 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 132 "pure2-autodiff.cpp2" +#line 146 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -431,6 +440,23 @@ auto main() -> int; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } +#line 127 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ + cpp2::impl::deferred_init r; +#line 128 "pure2-autodiff.cpp2" + std::vector v {}; + + CPP2_UFCS(push_back)(v, x); + CPP2_UFCS(push_back)(v, y); + + r.construct(0.0); + for ( + auto const& t : cpp2::move(v) ) + { + r.value() = r.value() + t; + }return std::move(r.value()); + } + [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d; @@ -668,12 +694,40 @@ int i_d {0}; return { std::move(r), std::move(r_d) }; } -#line 128 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::for_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_diff_ret{ + double r {0.0}; + double r_d {0.0}; +std::vector v_d {}; + + std::vector v {}; + CPP2_UFCS(push_back)(v, x); + CPP2_UFCS(push_back)(v_d, x_d); + CPP2_UFCS(push_back)(v, y); + CPP2_UFCS(push_back)(v_d, y_d); + r_d = { }; + r = 0.0; +{ +auto t_d_iter{CPP2_UFCS(begin)(cpp2::move(v_d))}; + for ( auto const& t : cpp2::move(v) ) { do { +{ +auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; + { + r_d = r_d + t_d; + r = r + t; + } +} + } + while (false); (++t_d_iter); } +} + return { std::move(r), std::move(r_d) }; + } + +#line 142 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 132 "pure2-autodiff.cpp2" +#line 146 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -702,6 +756,7 @@ auto main() -> int{ write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 3d9427c60..75b420ce7 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -239,6 +239,23 @@ ad_test:/* @autodiff @print */ type = return; } + for_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + v: std::vector = (); + v.push_back(x); + v.push_back(y); + r = 0.0; + for v + do (in t: _) + { + r = r + t; + } + return; + } + add_1_diff:( in x: double, in x_d: double, @@ -645,6 +662,38 @@ ad_test:/* @autodiff @print */ type = while i < 2; return; } + + for_loop_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + v_d: std::vector = (); + v: std::vector = (); + v.push_back(x); + v_d.push_back(x_d); + v.push_back(y); + v_d.push_back(y_d); + r_d = (); + r = 0.0; + (copy t_d_iter: _ = v_d.begin(), ) + for v + next (t_d_iter++) + do (in t: _) + { + (in t_d: _ = t_d_iter*, ) + { + r_d = r_d + t_d; + r = r + t; + } + } + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index af4052d3b..e079c6e95 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -103,91 +103,94 @@ class value_member_info; class simple_traverser; #line 3906 "reflect.h2" +class autodiff_special_func; + +#line 3929 "reflect.h2" class autodiff_context; -#line 3929 "reflect.h2" +#line 3979 "reflect.h2" class autodiff_handler_base; -#line 3943 "reflect.h2" +#line 3993 "reflect.h2" class autodiff_expression_handler; -#line 4223 "reflect.h2" +#line 4273 "reflect.h2" class autodiff_stmt_handler; -#line 4817 "reflect.h2" +#line 5058 "reflect.h2" class expression_flags; -#line 4833 "reflect.h2" +#line 5074 "reflect.h2" class regex_token; -#line 4860 "reflect.h2" +#line 5101 "reflect.h2" class regex_token_check; -#line 4881 "reflect.h2" +#line 5122 "reflect.h2" class regex_token_code; -#line 4902 "reflect.h2" +#line 5143 "reflect.h2" class regex_token_empty; -#line 4920 "reflect.h2" +#line 5161 "reflect.h2" class regex_token_list; -#line 4972 "reflect.h2" +#line 5213 "reflect.h2" class parse_context_group_state; -#line 5033 "reflect.h2" +#line 5274 "reflect.h2" class parse_context_branch_reset_state; -#line 5076 "reflect.h2" +#line 5317 "reflect.h2" class parse_context; -#line 5477 "reflect.h2" +#line 5718 "reflect.h2" class generation_function_context; -#line 5495 "reflect.h2" +#line 5736 "reflect.h2" class generation_context; -#line 5694 "reflect.h2" +#line 5935 "reflect.h2" class alternative_token; -#line 5709 "reflect.h2" +#line 5950 "reflect.h2" class alternative_token_gen; -#line 5774 "reflect.h2" +#line 6015 "reflect.h2" class any_token; -#line 5791 "reflect.h2" +#line 6032 "reflect.h2" class atomic_group_token; -#line 5821 "reflect.h2" +#line 6062 "reflect.h2" class char_token; -#line 5936 "reflect.h2" +#line 6177 "reflect.h2" class class_token; -#line 6160 "reflect.h2" +#line 6401 "reflect.h2" class group_ref_token; -#line 6297 "reflect.h2" +#line 6538 "reflect.h2" class group_token; -#line 6644 "reflect.h2" +#line 6885 "reflect.h2" class lookahead_lookbehind_token; -#line 6739 "reflect.h2" +#line 6980 "reflect.h2" class range_token; -#line 6896 "reflect.h2" +#line 7137 "reflect.h2" class special_range_token; -#line 6982 "reflect.h2" +#line 7223 "reflect.h2" template class regex_generator; -#line 7239 "reflect.h2" +#line 7480 "reflect.h2" } } @@ -1592,6 +1595,30 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; #line 3906 "reflect.h2" +class autodiff_special_func { + public: std::string name; + public: int n_args; + public: bool has_return; + public: bool is_member; + + public: std::string code; + + public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = ""); + +#line 3922 "reflect.h2" + public: autodiff_special_func(autodiff_special_func const& that); +#line 3922 "reflect.h2" + public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; +#line 3922 "reflect.h2" + public: autodiff_special_func(autodiff_special_func&& that) noexcept; +#line 3922 "reflect.h2" + public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; + + public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; + +#line 3927 "reflect.h2" +}; + class autodiff_context { private: int temporary_count {0}; public: std::map math_funcs { @@ -1599,17 +1626,29 @@ class autodiff_context { std::make_pair("cos", "-sin(_x_)"), std::make_pair("exp", "exp(_x_)")}; -#line 3915 "reflect.h2" +#line 3945 "reflect.h2" + public: std::vector special_funcs { + autodiff_special_func("push_back", 1, false, true, + "_o_.push_back(_a1_);\n" + "_od_.push_back(_ad1_);\n")}; + +#line 3951 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 3921 "reflect.h2" +#line 3957 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; +struct lookup_special_function_handling_ret { bool m; std::string code; }; + + + +#line 3964 "reflect.h2" + public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3927 "reflect.h2" +#line 3977 "reflect.h2" }; class autodiff_handler_base { @@ -1618,21 +1657,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3934 "reflect.h2" +#line 3984 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3938 "reflect.h2" +#line 3988 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3941 "reflect.h2" +#line 3991 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3947 "reflect.h2" +#line 3997 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1641,129 +1680,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); -#line 3960 "reflect.h2" +#line 4010 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 3979 "reflect.h2" +#line 4029 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 3988 "reflect.h2" +#line 4038 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4026 "reflect.h2" +#line 4076 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 4040 "reflect.h2" +#line 4090 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4044 "reflect.h2" +#line 4094 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4048 "reflect.h2" +#line 4098 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4052 "reflect.h2" +#line 4102 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4056 "reflect.h2" +#line 4106 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4060 "reflect.h2" +#line 4110 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4064 "reflect.h2" +#line 4114 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4068 "reflect.h2" +#line 4118 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4072 "reflect.h2" +#line 4122 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4076 "reflect.h2" +#line 4126 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4080 "reflect.h2" +#line 4130 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4084 "reflect.h2" +#line 4134 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4107 "reflect.h2" +#line 4157 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4150 "reflect.h2" +#line 4200 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4154 "reflect.h2" - public: auto traverse(cpp2::impl::in postfix) -> void override; +#line 4204 "reflect.h2" + public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4159 "reflect.h2" +#line 4209 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4203 "reflect.h2" +#line 4253 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4221 "reflect.h2" +#line 4271 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4227 "reflect.h2" +#line 4277 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4236 "reflect.h2" +#line 4286 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; + +#line 4312 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4241 "reflect.h2" +#line 4317 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4246 "reflect.h2" +#line 4322 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4259 "reflect.h2" +#line 4335 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4264 "reflect.h2" +#line 4340 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4269 "reflect.h2" +#line 4345 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4274 "reflect.h2" +#line 4350 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4282 "reflect.h2" +#line 4358 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4298 "reflect.h2" +#line 4374 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4329 "reflect.h2" +#line 4421 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4340 "reflect.h2" +#line 4432 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; + +#line 4460 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4465 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4469 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4473 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4477 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4481 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4485 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4489 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4493 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4497 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4501 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4505 "reflect.h2" + public: auto traverse(cpp2::impl::in binexpr) -> void override; + +#line 4509 "reflect.h2" + public: auto traverse(cpp2::impl::in isas) -> void override; + +#line 4513 "reflect.h2" + public: auto traverse(cpp2::impl::in prefix) -> void override; + +#line 4518 "reflect.h2" + public: auto traverse(cpp2::impl::in postfix) -> void override; + +#line 4604 "reflect.h2" + public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4367 "reflect.h2" +#line 4608 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4813 "reflect.h2" +#line 5054 "reflect.h2" using error_func = std::function x)>; -#line 4817 "reflect.h2" +#line 5058 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1798,20 +1888,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4825 "reflect.h2" +#line 5066 "reflect.h2" }; -#line 4833 "reflect.h2" +#line 5074 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4841 "reflect.h2" +#line 5082 "reflect.h2" public: explicit regex_token(); -#line 4846 "reflect.h2" +#line 5087 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1823,103 +1913,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4852 "reflect.h2" +#line 5093 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4858 "reflect.h2" +#line 5099 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4864 "reflect.h2" +#line 5105 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4871 "reflect.h2" +#line 5112 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4875 "reflect.h2" +#line 5116 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4876 "reflect.h2" +#line 5117 "reflect.h2" }; -#line 4879 "reflect.h2" +#line 5120 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4885 "reflect.h2" +#line 5126 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4892 "reflect.h2" +#line 5133 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4896 "reflect.h2" +#line 5137 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4897 "reflect.h2" +#line 5138 "reflect.h2" }; -#line 4900 "reflect.h2" +#line 5141 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4906 "reflect.h2" +#line 5147 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4910 "reflect.h2" +#line 5151 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4914 "reflect.h2" +#line 5155 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4915 "reflect.h2" +#line 5156 "reflect.h2" }; -#line 4918 "reflect.h2" +#line 5159 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4924 "reflect.h2" +#line 5165 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4931 "reflect.h2" +#line 5172 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4937 "reflect.h2" +#line 5178 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4943 "reflect.h2" +#line 5184 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4951 "reflect.h2" +#line 5192 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -1927,10 +2017,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4963 "reflect.h2" +#line 5204 "reflect.h2" }; -#line 4966 "reflect.h2" +#line 5207 "reflect.h2" // // Parse and generation context. // @@ -1946,33 +2036,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4986 "reflect.h2" +#line 5227 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4993 "reflect.h2" +#line 5234 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5005 "reflect.h2" +#line 5246 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5010 "reflect.h2" +#line 5251 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5014 "reflect.h2" +#line 5255 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5028 "reflect.h2" +#line 5269 "reflect.h2" }; -#line 5031 "reflect.h2" +#line 5272 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -1985,25 +2075,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5049 "reflect.h2" +#line 5290 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5055 "reflect.h2" +#line 5296 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5062 "reflect.h2" +#line 5303 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5069 "reflect.h2" +#line 5310 "reflect.h2" }; -#line 5072 "reflect.h2" +#line 5313 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2019,7 +2109,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5088 "reflect.h2" +#line 5329 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2027,64 +2117,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5099 "reflect.h2" +#line 5340 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5112 "reflect.h2" +#line 5353 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5120 "reflect.h2" +#line 5361 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5124 "reflect.h2" +#line 5365 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5128 "reflect.h2" +#line 5369 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5140 "reflect.h2" +#line 5381 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5147 "reflect.h2" +#line 5388 "reflect.h2" public: auto next_alternative() & -> void; -#line 5153 "reflect.h2" +#line 5394 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5159 "reflect.h2" +#line 5400 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5163 "reflect.h2" +#line 5404 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5174 "reflect.h2" +#line 5415 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5178 "reflect.h2" +#line 5419 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5184 "reflect.h2" +#line 5425 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5188 "reflect.h2" +#line 5429 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5195 "reflect.h2" +#line 5436 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5206 "reflect.h2" +#line 5447 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2092,51 +2182,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5250 "reflect.h2" +#line 5491 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5262 "reflect.h2" +#line 5503 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5275 "reflect.h2" +#line 5516 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5298 "reflect.h2" +#line 5539 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5315 "reflect.h2" +#line 5556 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5336 "reflect.h2" +#line 5577 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5346 "reflect.h2" +#line 5587 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5350 "reflect.h2" +#line 5591 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5406 "reflect.h2" +#line 5647 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5445 "reflect.h2" +#line 5686 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5460 "reflect.h2" +#line 5701 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2148,10 +2238,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5471 "reflect.h2" +#line 5712 "reflect.h2" }; -#line 5474 "reflect.h2" +#line 5715 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2161,16 +2251,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5488 "reflect.h2" +#line 5729 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5491 "reflect.h2" +#line 5732 "reflect.h2" }; -#line 5494 "reflect.h2" +#line 5735 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2190,68 +2280,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5516 "reflect.h2" +#line 5757 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5522 "reflect.h2" +#line 5763 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5531 "reflect.h2" +#line 5772 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5542 "reflect.h2" +#line 5783 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5549 "reflect.h2" +#line 5790 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5569 "reflect.h2" +#line 5810 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5579 "reflect.h2" +#line 5820 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5602 "reflect.h2" +#line 5843 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5610 "reflect.h2" +#line 5851 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5614 "reflect.h2" +#line 5855 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5620 "reflect.h2" +#line 5861 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5626 "reflect.h2" +#line 5867 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5636 "reflect.h2" +#line 5877 "reflect.h2" public: auto finish_context() & -> void; -#line 5644 "reflect.h2" +#line 5885 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5650 "reflect.h2" +#line 5891 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5654 "reflect.h2" +#line 5895 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5658 "reflect.h2" +#line 5899 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5682 "reflect.h2" +#line 5923 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2259,7 +2349,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5688 "reflect.h2" +#line 5929 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2279,27 +2369,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5707 "reflect.h2" +#line 5948 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5713 "reflect.h2" +#line 5954 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5720 "reflect.h2" +#line 5961 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5737 "reflect.h2" +#line 5978 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5744 "reflect.h2" +#line 5985 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5757 "reflect.h2" +#line 5998 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2307,19 +2397,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5769 "reflect.h2" +#line 6010 "reflect.h2" }; -#line 5772 "reflect.h2" +#line 6013 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5778 "reflect.h2" +#line 6019 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5782 "reflect.h2" +#line 6023 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2327,7 +2417,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5787 "reflect.h2" +#line 6028 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2335,17 +2425,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5795 "reflect.h2" +#line 6036 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5806 "reflect.h2" +#line 6047 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5814 "reflect.h2" +#line 6055 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2353,7 +2443,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5817 "reflect.h2" +#line 6058 "reflect.h2" }; // Regex syntax: a @@ -2361,34 +2451,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5825 "reflect.h2" +#line 6066 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5834 "reflect.h2" +#line 6075 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5840 "reflect.h2" +#line 6081 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5844 "reflect.h2" +#line 6085 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5867 "reflect.h2" +#line 6108 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5888 "reflect.h2" +#line 6129 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5906 "reflect.h2" +#line 6147 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5921 "reflect.h2" +#line 6162 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5927 "reflect.h2" +#line 6168 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2396,33 +2486,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5931 "reflect.h2" +#line 6172 "reflect.h2" }; -#line 5934 "reflect.h2" +#line 6175 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5940 "reflect.h2" +#line 6181 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5952 "reflect.h2" +#line 6193 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6078 "reflect.h2" +#line 6319 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6087 "reflect.h2" +#line 6328 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6092 "reflect.h2" +#line 6333 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2430,20 +2520,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6099 "reflect.h2" +#line 6340 "reflect.h2" }; -#line 6102 "reflect.h2" +#line 6343 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6143 "reflect.h2" +#line 6384 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6154 "reflect.h2" +#line 6395 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2453,20 +2543,20 @@ class class_token class group_ref_token : public regex_token { -#line 6164 "reflect.h2" +#line 6405 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6176 "reflect.h2" +#line 6417 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6277 "reflect.h2" +#line 6518 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6281 "reflect.h2" +#line 6522 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2474,10 +2564,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6284 "reflect.h2" +#line 6525 "reflect.h2" }; -#line 6287 "reflect.h2" +#line 6528 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2491,29 +2581,29 @@ class group_ref_token class group_token : public regex_token { -#line 6301 "reflect.h2" +#line 6542 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6323 "reflect.h2" +#line 6564 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6337 "reflect.h2" +#line 6578 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6496 "reflect.h2" +#line 6737 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6504 "reflect.h2" +#line 6745 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6522 "reflect.h2" +#line 6763 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6553 "reflect.h2" +#line 6794 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2522,25 +2612,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6560 "reflect.h2" +#line 6801 "reflect.h2" }; -#line 6563 "reflect.h2" +#line 6804 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6604 "reflect.h2" +#line 6845 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6624 "reflect.h2" +#line 6865 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6640 "reflect.h2" +#line 6881 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2548,20 +2638,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6648 "reflect.h2" +#line 6889 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6657 "reflect.h2" +#line 6898 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6668 "reflect.h2" +#line 6909 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6675 "reflect.h2" +#line 6916 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2569,26 +2659,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6678 "reflect.h2" +#line 6919 "reflect.h2" }; -#line 6681 "reflect.h2" +#line 6922 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6709 "reflect.h2" +#line 6950 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6737 "reflect.h2" +#line 6978 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6743 "reflect.h2" +#line 6984 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2598,22 +2688,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6823 "reflect.h2" +#line 7064 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6835 "reflect.h2" +#line 7076 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6848 "reflect.h2" +#line 7089 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6867 "reflect.h2" +#line 7108 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6877 "reflect.h2" +#line 7118 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6888 "reflect.h2" +#line 7129 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2621,16 +2711,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6891 "reflect.h2" +#line 7132 "reflect.h2" }; -#line 6894 "reflect.h2" +#line 7135 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6900 "reflect.h2" +#line 7141 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2639,7 +2729,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6930 "reflect.h2" +#line 7171 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2648,14 +2738,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6952 "reflect.h2" +#line 7193 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6974 "reflect.h2" +#line 7215 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2676,24 +2766,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6997 "reflect.h2" +#line 7238 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7032 "reflect.h2" +#line 7273 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7046 "reflect.h2" +#line 7287 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7058 "reflect.h2" +#line 7299 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7113 "reflect.h2" +#line 7354 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2704,7 +2794,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7239 "reflect.h2" +#line 7480 "reflect.h2" } } @@ -7207,17 +7297,75 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // autodiff - stub // -#line 3912 "reflect.h2" +#line 3914 "reflect.h2" + autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_) + : name{ name_ } + , n_args{ n_args_ } + , has_return{ has_return_ } + , is_member{ is_member_ } + , code{ code_ }{ + +#line 3920 "reflect.h2" + } + +#line 3922 "reflect.h2" + autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) + : name{ that.name } + , n_args{ that.n_args } + , has_return{ that.has_return } + , is_member{ that.is_member } + , code{ that.code }{} +#line 3922 "reflect.h2" + auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { + name = that.name; + n_args = that.n_args; + has_return = that.has_return; + is_member = that.is_member; + code = that.code; + return *this; } +#line 3922 "reflect.h2" + autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept + : name{ std::move(that).name } + , n_args{ std::move(that).n_args } + , has_return{ std::move(that).has_return } + , is_member{ std::move(that).is_member } + , code{ std::move(that).code }{} +#line 3922 "reflect.h2" + auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { + name = std::move(that).name; + n_args = std::move(that).n_args; + has_return = std::move(that).has_return; + is_member = std::move(that).is_member; + code = std::move(that).code; + return *this; }// Default copy. + +#line 3924 "reflect.h2" + [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ + return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; + } + +#line 3935 "reflect.h2" // TODO: Extend -#line 3915 "reflect.h2" +#line 3938 "reflect.h2" + // Code in special function is replaced. Placeholders are: + // _o_ : name of object for member functions. + // _o_ : name of derivative object for member functions. + // _a1_ : First argument value + // _ad1_: First derivative argument value + // _a2_ : Second argument value + // _ad2_: Second derivative argument value + + /* has_return = */ /* is_member = */ + +#line 3951 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 3921 "reflect.h2" +#line 3957 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ // TODO: Add type to required generation for AD. @@ -7225,27 +7373,45 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return type; // Use the same type for now. } -#line 3934 "reflect.h2" +#line 3964 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ + cpp2::impl::deferred_init m; + cpp2::impl::deferred_init code; +#line 3965 "reflect.h2" + autodiff_special_func lookup {func_name, n_args, has_return, is_member}; + + m.construct(false); + code.construct(""); + for ( auto const& func : special_funcs ) { + if (CPP2_UFCS(is_match)(func, lookup)) { + m.value() = true; + code.value() = func.code; + return { std::move(m.value()), std::move(code.value()) }; + } + }return { std::move(m.value()), std::move(code.value()) }; + } + +#line 3984 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3936 "reflect.h2" +#line 3986 "reflect.h2" } -#line 3934 "reflect.h2" +#line 3984 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3936 "reflect.h2" +#line 3986 "reflect.h2" } -#line 3938 "reflect.h2" +#line 3988 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 3953 "reflect.h2" +#line 4003 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7253,10 +7419,10 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_ } , declare_d{ declare_ }{ -#line 3958 "reflect.h2" +#line 4008 "reflect.h2" } -#line 3960 "reflect.h2" +#line 4010 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + "_d"}; if (lhs == "_") { @@ -7276,7 +7442,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 3979 "reflect.h2" +#line 4029 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7286,7 +7452,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 3988 "reflect.h2" +#line 4038 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7325,7 +7491,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4026 "reflect.h2" +#line 4076 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7340,62 +7506,62 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return true; } -#line 4040 "reflect.h2" +#line 4090 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4044 "reflect.h2" +#line 4094 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4048 "reflect.h2" +#line 4098 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4052 "reflect.h2" +#line 4102 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4056 "reflect.h2" +#line 4106 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4060 "reflect.h2" +#line 4110 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4064 "reflect.h2" +#line 4114 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4068 "reflect.h2" +#line 4118 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4072 "reflect.h2" +#line 4122 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4076 "reflect.h2" +#line 4126 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4080 "reflect.h2" +#line 4130 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4084 "reflect.h2" +#line 4134 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7419,7 +7585,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4107 "reflect.h2" +#line 4157 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7446,7 +7612,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4134 "reflect.h2" +#line 4184 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7463,18 +7629,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4150 "reflect.h2" +#line 4200 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4154 "reflect.h2" - auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void +#line 4204 "reflect.h2" + auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { - CPP2_UFCS(error)(postfix, "AD: Prefix expressions are not yet handled."); + CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4159 "reflect.h2" +#line 4209 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7519,7 +7685,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // TODO: Add function to list of functions/objects for differentiation. } -#line 4203 "reflect.h2" +#line 4253 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7539,26 +7705,57 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}}} } -#line 4231 "reflect.h2" +#line 4281 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4234 "reflect.h2" +#line 4284 "reflect.h2" } -#line 4236 "reflect.h2" +#line 4286 "reflect.h2" + [[nodiscard]] auto autodiff_stmt_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ + + auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), false, !(CPP2_UFCS(empty)(object)))}; + + if (!(r.m)) { + return false; // No match + } + + // Have a match, do the replacement + std::string code {""}; + code = cpp2::move(r).code;// TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + + code = string_util::replace_all(code, "_o_", object); + code = string_util::replace_all(code, "_od_", object_d); +{ +auto i{1}; + +#line 4302 "reflect.h2" + for ( auto const& arg : args ) { + code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); + code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); + } +} + +#line 4307 "reflect.h2" + diff += cpp2::move(code); + + return true; + } + +#line 4312 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4241 "reflect.h2" +#line 4317 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4246 "reflect.h2" +#line 4322 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ auto lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7571,22 +7768,22 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + " = " + cpp2::to_string(cpp2::move(init)) + ";\n"; } -#line 4259 "reflect.h2" +#line 4335 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4264 "reflect.h2" +#line 4340 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4269 "reflect.h2" +#line 4345 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4274 "reflect.h2" +#line 4350 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7594,7 +7791,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in diff += "}\n"; } -#line 4282 "reflect.h2" +#line 4358 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7610,7 +7807,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4298 "reflect.h2" +#line 4374 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -7624,7 +7821,6 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } else {if (CPP2_UFCS(is_do)(stmt)) { // TODO: Assumption is here that nothing is in the condition - diff += "do "; pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); @@ -7636,12 +7832,29 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } else { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_for)(stmt)) ) { cpp2::cpp2_default.report_violation(""); } + // No zip view available in cpp 20 do a piggy back for range - CPP2_UFCS(error)(stmt, "AD: Do not know how to handle for loops: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); + // TODO: Assumption that this is just an id expression. + auto range {CPP2_UFCS(to_string)(CPP2_UFCS(get_for_range)(stmt))}; + + auto param {CPP2_UFCS(get_for_parameter)(stmt)}; + auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; + auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; + diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + "_d.begin())\n"; + diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; + if (CPP2_UFCS(has_next)(stmt)) { + // TODO: Assumption is here that nothing is in the next expression + diff += "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "; + } + diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; + diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; + diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d: " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + pre_traverse(CPP2_UFCS(get_for_body)(stmt)); + diff += "}\n"; }} } -#line 4329 "reflect.h2" +#line 4421 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7653,7 +7866,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4340 "reflect.h2" +#line 4432 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7678,11 +7891,184 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in append(cpp2::move(h)); } else { - CPP2_UFCS(error)(mf, "AD: Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(expr)) + ""); + base::traverse(expr); + } + } + +#line 4460 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + // TDOO: Move meta::expression logic here + CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); + } + +#line 4465 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); + } + +#line 4469 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); + } + +#line 4473 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); + } + +#line 4477 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); + } + +#line 4481 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); + } + +#line 4485 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); + } + +#line 4489 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); + } + +#line 4493 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); + } + +#line 4497 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); + } + +#line 4501 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); + } + +#line 4505 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ + CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); + } + +#line 4509 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ + CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); + } + +#line 4513 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void + { + CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); + } + +#line 4518 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void + { + // TODO: Unify with autodiff_expression_handler implementation + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + auto is_func {true}; +{ +auto i{0}; + +#line 4526 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + continue; + } + if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + continue; + } + + is_func = false; + } while (false); i += 1; } +} + + // Check for function call, everything else is not handled. +#line 4538 "reflect.h2" + if (!((cpp2::move(is_func)))) { + CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + return ; + } + + std::string object {""}; + std::string object_d {""}; + std::string function_name {""}; + std::vector args {}; + + auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; + +#line 4551 "reflect.h2" + if (1 != CPP2_UFCS(ssize)(terms)) { + object = CPP2_UFCS(to_string)(primary); + object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + "_d"; + } + else { + function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); + } +{ +auto i{0}; + +#line 4560 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } + auto name {CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term))}; + + if (i + 2 == CPP2_UFCS(ssize)(terms)) {// Second last term is function name, last term is function argument list + function_name = cpp2::move(name); + } + else { + object += "." + name; + object_d += "." + cpp2::move(name); + } + } + else {if (CPP2_UFCS(get_op)(term) == "(") { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_expression_list)(term)) ) { cpp2::cpp2_default.report_violation(""); } + + autodiff_expression_handler ad {ctx, ""}; + args = CPP2_UFCS(handle_expression_list)(ad, CPP2_UFCS(get_expression_list)(term)); + append(cpp2::move(ad)); + } + else { + CPP2_UFCS(error)(postfix, "AD: Do not know how to handle postfix term: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + ""); + }} + } while (false); i += 1; } +} + +#line 4585 "reflect.h2" + if (handle_special_function(object, cpp2::move(object_d), function_name, args)) { + return ; + } + + // No special handling, currently only allow direct function calls + if (!(CPP2_UFCS(empty)(cpp2::move(object)))) { + CPP2_UFCS(error)(postfix, "AD: Can currently only handle direct function calls and no member function calls.: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); } + + // TODO: This is untested. Requires handling of out and inout parameters in functions. + // All arguments have now been handled. Form the function call + diff += "" + cpp2::to_string(cpp2::move(function_name)) + "_diff("; + for ( auto const& arg : cpp2::move(args) ) { + diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; + } + diff += ");\n"; + } -#line 4369 "reflect.h2" +#line 4604 "reflect.h2" + auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void + { + CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); + } + +#line 4610 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -7734,7 +8120,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4421 "reflect.h2" +#line 4662 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -7838,7 +8224,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4434 "reflect.h2" +#line 4675 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8203,7 +8589,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 4799 "reflect.h2" +#line 5040 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8219,11 +8605,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4815 "reflect.h2" +#line 5056 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4819 "reflect.h2" +#line 5060 "reflect.h2" // mod: i // mod: m // mod: s @@ -8231,116 +8617,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4828 "reflect.h2" +#line 5069 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4837 "reflect.h2" +#line 5078 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4839 "reflect.h2" +#line 5080 "reflect.h2" } -#line 4841 "reflect.h2" +#line 5082 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4843 "reflect.h2" +#line 5084 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4849 "reflect.h2" +#line 5090 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4850 "reflect.h2" +#line 5091 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4851 "reflect.h2" +#line 5092 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4866 "reflect.h2" +#line 5107 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4869 "reflect.h2" +#line 5110 "reflect.h2" } -#line 4871 "reflect.h2" +#line 5112 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4875 "reflect.h2" +#line 5116 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4887 "reflect.h2" +#line 5128 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4890 "reflect.h2" +#line 5131 "reflect.h2" } -#line 4892 "reflect.h2" +#line 5133 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4896 "reflect.h2" +#line 5137 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4906 "reflect.h2" +#line 5147 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4908 "reflect.h2" +#line 5149 "reflect.h2" } -#line 4910 "reflect.h2" +#line 5151 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4914 "reflect.h2" +#line 5155 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4926 "reflect.h2" +#line 5167 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4929 "reflect.h2" +#line 5170 "reflect.h2" } -#line 4931 "reflect.h2" +#line 5172 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4937 "reflect.h2" +#line 5178 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4943 "reflect.h2" +#line 5184 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8349,7 +8735,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4951 "reflect.h2" +#line 5192 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8365,7 +8751,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4979 "reflect.h2" +#line 5220 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8373,14 +8759,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4987 "reflect.h2" +#line 5228 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4994 "reflect.h2" +#line 5235 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8392,15 +8778,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5006 "reflect.h2" +#line 5247 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5011 "reflect.h2" +#line 5252 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5015 "reflect.h2" +#line 5256 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8421,7 +8807,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5041 "reflect.h2" +#line 5282 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8430,20 +8816,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5050 "reflect.h2" +#line 5291 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5056 "reflect.h2" +#line 5297 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5063 "reflect.h2" +#line 5304 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8458,16 +8844,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5093 "reflect.h2" +#line 5334 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5097 "reflect.h2" +#line 5338 "reflect.h2" } -#line 5103 "reflect.h2" +#line 5344 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8477,7 +8863,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5113 "reflect.h2" +#line 5354 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8485,17 +8871,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5120 "reflect.h2" +#line 5361 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5124 "reflect.h2" +#line 5365 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5131 "reflect.h2" +#line 5372 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8505,7 +8891,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5140 "reflect.h2" +#line 5381 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8513,24 +8899,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5147 "reflect.h2" +#line 5388 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5155 "reflect.h2" +#line 5396 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5159 "reflect.h2" +#line 5400 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5163 "reflect.h2" +#line 5404 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8542,22 +8928,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5174 "reflect.h2" +#line 5415 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5180 "reflect.h2" +#line 5421 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5184 "reflect.h2" +#line 5425 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5188 "reflect.h2" +#line 5429 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8565,7 +8951,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5195 "reflect.h2" +#line 5436 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8577,10 +8963,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5208 "reflect.h2" +#line 5449 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5211 "reflect.h2" +#line 5452 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8620,7 +9006,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5251 "reflect.h2" +#line 5492 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8632,14 +9018,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5262 "reflect.h2" +#line 5503 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5263 "reflect.h2" +#line 5504 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5264 "reflect.h2" +#line 5505 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5266 "reflect.h2" +#line 5507 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8649,10 +9035,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5275 "reflect.h2" +#line 5516 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5277 "reflect.h2" +#line 5518 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8674,14 +9060,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5298 "reflect.h2" +#line 5539 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5299 "reflect.h2" +#line 5540 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5300 "reflect.h2" +#line 5541 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5302 "reflect.h2" +#line 5543 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8695,7 +9081,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5315 "reflect.h2" +#line 5556 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8717,7 +9103,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5336 "reflect.h2" +#line 5577 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8728,12 +9114,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5346 "reflect.h2" +#line 5587 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5347 "reflect.h2" +#line 5588 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5352 "reflect.h2" +#line 5593 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8788,7 +9174,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5406 "reflect.h2" +#line 5647 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -8828,7 +9214,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5445 "reflect.h2" +#line 5686 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -8844,21 +9230,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5462 "reflect.h2" +#line 5703 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5463 "reflect.h2" +#line 5704 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5464 "reflect.h2" +#line 5705 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5466 "reflect.h2" +#line 5707 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5481 "reflect.h2" +#line 5722 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -8866,7 +9252,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5488 "reflect.h2" +#line 5729 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -8876,22 +9262,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5506 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5511 "reflect.h2" +#line 5752 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5517 "reflect.h2" +#line 5758 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5523 "reflect.h2" +#line 5764 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -8900,7 +9286,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5531 "reflect.h2" +#line 5772 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -8912,7 +9298,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5542 "reflect.h2" +#line 5783 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -8920,7 +9306,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5549 "reflect.h2" +#line 5790 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -8941,7 +9327,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5570 "reflect.h2" +#line 5811 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -8951,7 +9337,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5580 "reflect.h2" +#line 5821 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -8974,33 +9360,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5604 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5610 "reflect.h2" +#line 5851 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5614 "reflect.h2" +#line 5855 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5620 "reflect.h2" +#line 5861 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5628 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9009,7 +9395,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5636 "reflect.h2" +#line 5877 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9018,22 +9404,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5646 "reflect.h2" +#line 5887 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5650 "reflect.h2" +#line 5891 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5654 "reflect.h2" +#line 5895 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5658 "reflect.h2" +#line 5899 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9057,18 +9443,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5683 "reflect.h2" +#line 5924 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5698 "reflect.h2" +#line 5939 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5700 "reflect.h2" +#line 5941 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9079,15 +9465,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5715 "reflect.h2" +#line 5956 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5718 "reflect.h2" +#line 5959 "reflect.h2" } -#line 5720 "reflect.h2" +#line 5961 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9105,7 +9491,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5737 "reflect.h2" +#line 5978 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9113,7 +9499,7 @@ generation_function_context::generation_function_context(){} } } -#line 5744 "reflect.h2" +#line 5985 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9127,7 +9513,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5757 "reflect.h2" +#line 5998 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9143,14 +9529,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5778 "reflect.h2" +#line 6019 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5780 "reflect.h2" +#line 6021 "reflect.h2" } -#line 5782 "reflect.h2" +#line 6023 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9159,11 +9545,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5797 "reflect.h2" +#line 6038 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5799 "reflect.h2" +#line 6040 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9171,7 +9557,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5806 "reflect.h2" +#line 6047 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9180,37 +9566,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5814 "reflect.h2" +#line 6055 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5828 "reflect.h2" +#line 6069 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5832 "reflect.h2" +#line 6073 "reflect.h2" } -#line 5834 "reflect.h2" +#line 6075 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5838 "reflect.h2" +#line 6079 "reflect.h2" } -#line 5840 "reflect.h2" +#line 6081 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5844 "reflect.h2" +#line 6085 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9219,14 +9605,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5850 "reflect.h2" +#line 6091 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5855 "reflect.h2" +#line 6096 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9239,7 +9625,7 @@ size_t i{0}; } } -#line 5867 "reflect.h2" +#line 6108 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9261,7 +9647,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5888 "reflect.h2" +#line 6129 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9280,7 +9666,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5906 "reflect.h2" +#line 6147 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9296,14 +9682,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5921 "reflect.h2" +#line 6162 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5927 "reflect.h2" +#line 6168 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9311,19 +9697,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5944 "reflect.h2" +#line 6185 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5945 "reflect.h2" +#line 6186 "reflect.h2" { -#line 5950 "reflect.h2" +#line 6191 "reflect.h2" } -#line 5953 "reflect.h2" +#line 6194 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9449,7 +9835,7 @@ size_t i{0}; ); } -#line 6078 "reflect.h2" +#line 6319 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9459,13 +9845,13 @@ size_t i{0}; ); } -#line 6087 "reflect.h2" +#line 6328 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6092 "reflect.h2" +#line 6333 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9476,12 +9862,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6104 "reflect.h2" +#line 6345 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6109 "reflect.h2" +#line 6350 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9515,7 +9901,7 @@ size_t i{0}; } -#line 6145 "reflect.h2" +#line 6386 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9524,19 +9910,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6168 "reflect.h2" +#line 6409 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6169 "reflect.h2" +#line 6410 "reflect.h2" { -#line 6174 "reflect.h2" +#line 6415 "reflect.h2" } -#line 6176 "reflect.h2" +#line 6417 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9638,19 +10024,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6277 "reflect.h2" +#line 6518 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6281 "reflect.h2" +#line 6522 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6305 "reflect.h2" +#line 6546 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9669,7 +10055,7 @@ size_t i{0}; return r; } -#line 6323 "reflect.h2" +#line 6564 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9684,7 +10070,7 @@ size_t i{0}; return r; } -#line 6337 "reflect.h2" +#line 6578 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -9844,7 +10230,7 @@ size_t i{0}; } } -#line 6496 "reflect.h2" +#line 6737 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -9853,7 +10239,7 @@ size_t i{0}; return r; } -#line 6504 "reflect.h2" +#line 6745 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -9872,7 +10258,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6522 "reflect.h2" +#line 6763 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -9904,7 +10290,7 @@ size_t i{0}; } } -#line 6553 "reflect.h2" +#line 6794 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -9915,7 +10301,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6565 "reflect.h2" +#line 6806 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -9954,7 +10340,7 @@ size_t i{0}; return r; } -#line 6606 "reflect.h2" +#line 6847 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -9972,7 +10358,7 @@ size_t i{0}; }} } -#line 6626 "reflect.h2" +#line 6867 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -9986,16 +10372,16 @@ size_t i{0}; } } -#line 6652 "reflect.h2" +#line 6893 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6655 "reflect.h2" +#line 6896 "reflect.h2" } -#line 6657 "reflect.h2" +#line 6898 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10007,7 +10393,7 @@ size_t i{0}; } } -#line 6668 "reflect.h2" +#line 6909 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10015,14 +10401,14 @@ size_t i{0}; return r; } -#line 6675 "reflect.h2" +#line 6916 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6683 "reflect.h2" +#line 6924 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10048,7 +10434,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6711 "reflect.h2" +#line 6952 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10074,11 +10460,11 @@ size_t i{0}; return r; } -#line 6748 "reflect.h2" +#line 6989 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6750 "reflect.h2" +#line 6991 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10152,7 +10538,7 @@ size_t i{0}; return nullptr; } -#line 6823 "reflect.h2" +#line 7064 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10165,7 +10551,7 @@ size_t i{0}; }} } -#line 6835 "reflect.h2" +#line 7076 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10179,7 +10565,7 @@ size_t i{0}; }} } -#line 6848 "reflect.h2" +#line 7089 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10199,7 +10585,7 @@ size_t i{0}; return r; } -#line 6867 "reflect.h2" +#line 7108 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10210,7 +10596,7 @@ size_t i{0}; return r; } -#line 6877 "reflect.h2" +#line 7118 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10222,14 +10608,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6888 "reflect.h2" +#line 7129 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6900 "reflect.h2" +#line 7141 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10253,7 +10639,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6924 "reflect.h2" +#line 7165 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10263,7 +10649,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6936 "reflect.h2" +#line 7177 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10279,7 +10665,7 @@ size_t i{0}; } } -#line 6956 "reflect.h2" +#line 7197 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10297,15 +10683,15 @@ size_t i{0}; }} } -#line 6992 "reflect.h2" +#line 7233 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6995 "reflect.h2" +#line 7236 "reflect.h2" } -#line 6997 "reflect.h2" +#line 7238 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10341,7 +10727,7 @@ size_t i{0}; return source; } -#line 7032 "reflect.h2" +#line 7273 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10357,7 +10743,7 @@ size_t i{0}; } } -#line 7048 "reflect.h2" +#line 7289 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10366,7 +10752,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10421,7 +10807,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7117 "reflect.h2" +#line 7358 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10543,7 +10929,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7239 "reflect.h2" +#line 7480 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index c87f8a4ba..58d5de79c 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3903,6 +3903,29 @@ sample_traverser: (idexpr: meta::id_expression, indent: i32) = // autodiff - stub // +autodiff_special_func: type = { + public name : std::string; + public n_args : int; + public has_return: bool; + public is_member : bool; + + public code: std::string; + + operator=: (out this, name_: std::string, n_args_: int, has_return_: bool, is_member_: bool, code_: std::string = "") = { + name = name_; + n_args = n_args_; + has_return = has_return_; + is_member = is_member_; + code = code_; + } + + operator=: (out this, that) = {} // Default copy. + + is_match: (this, o: autodiff_special_func) -> bool = { + return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; + } +} + autodiff_context: type = { private temporary_count : int = 0; public math_funcs : std::map = ( @@ -3912,6 +3935,19 @@ autodiff_context: type = { // TODO: Extend ); + // Code in special function is replaced. Placeholders are: + // _o_ : name of object for member functions. + // _o_ : name of derivative object for member functions. + // _a1_ : First argument value + // _ad1_: First derivative argument value + // _a2_ : Second argument value + // _ad2_: Second derivative argument value + public special_funcs : std::vector = ( + autodiff_special_func("push_back", 1, /* has_return = */ false, /* is_member = */ true, + "_o_.push_back(_a1_);\n" + "_od_.push_back(_ad1_);\n") + ); + gen_temporary : (inout this) -> std::string = { temporary_count += 1; return "temp_(temporary_count)$"; @@ -3924,6 +3960,20 @@ autodiff_context: type = { return type; // Use the same type for now. } + + lookup_special_function_handling: (this, func_name: std::string, n_args: int, has_return: bool, is_member: bool) -> (m: bool, code: std::string) = { + lookup : autodiff_special_func = (func_name, n_args, has_return, is_member); + + m = false; + code = ""; + for special_funcs do (func) { + if func.is_match(lookup) { + m = true; + code = func.code; + return; + } + } + } } autodiff_handler_base: type = { @@ -4151,9 +4201,9 @@ autodiff_expression_handler: type = { isas.error( "AD: Is as expressions are not yet handled." ); } - traverse: (override inout this, postfix: meta::prefix_expression) = + traverse: (override inout this, prefix: meta::prefix_expression) = { - postfix.error( "AD: Prefix expressions are not yet handled." ); + prefix.error( "AD: Prefix expressions are not yet handled." ); } traverse: (override inout this, postfix: meta::postfix_expression) = @@ -4233,6 +4283,32 @@ autodiff_stmt_handler: type = { mf = mf_; } + handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { + + r := ctx*.lookup_special_function_handling(function_name, args.ssize(), false, !object.empty()); + + if !r.m { + return false; // No match + } + + // Have a match, do the replacement + code: std::string = ""; + code = r.code; // TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + + code = string_util::replace_all(code, "_o_", object); + code = string_util::replace_all(code, "_od_", object_d); + + (copy i := 1) + for args do (arg) { + code = string_util::replace_all(code, "_a(i)$_", arg); + code = string_util::replace_all(code, "_ad(i)$_", arg + "_d"); + } + + diff += code; + + return true; + } + traverse: (override inout this, decl: meta::declaration) = { base::traverse(decl); } @@ -4308,7 +4384,6 @@ autodiff_stmt_handler: type = { } else if stmt.is_do() { // TODO: Assumption is here that nothing is in the condition - diff += "do "; pre_traverse(stmt.get_do_while_body()); @@ -4320,8 +4395,25 @@ autodiff_stmt_handler: type = { } else { assert(stmt.is_for()); + // No zip view available in cpp 20 do a piggy back for range + + // TODO: Assumption that this is just an id expression. + range := stmt.get_for_range().to_string(); - stmt.error("AD: Do not know how to handle for loops: (stmt.to_string())$"); + param := stmt.get_for_parameter(); + param_style := to_string_view(param.get_passing_style()); + param_decl := param.get_declaration(); + diff += "(copy (param_decl.name())$_d_iter := (range)$_d.begin())\n"; + diff += "for (range)$ next ("; + if stmt.has_next() { + // TODO: Assumption is here that nothing is in the next expression + diff += "(stmt.get_next_expression().to_string())$, "; + } + diff += "(param_decl.name())$_d_iter++"; + diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; + diff += "((param_style)$ (param_decl.name())$_d: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; + pre_traverse(stmt.get_for_body()); + diff += "}\n"; } } @@ -4361,8 +4453,157 @@ autodiff_stmt_handler: type = { append(h); } else { - mf.error("AD: Do not know how to handle: (expr.to_string())$"); + base::traverse(expr); + } + } + + traverse: (override inout this, binexpr: meta::assignment_expression) = { + // TDOO: Move meta::expression logic here + binexpr.error( "AD: Assign expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::logical_or_expression) = { + binexpr.error( "AD: Logical or expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::logical_and_expression) = { + binexpr.error( "AD: Logical and expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::bit_or_expression) = { + binexpr.error( "AD: Bit or expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::bit_xor_expression) = { + binexpr.error( "AD: Bit xor expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::bit_and_expression) = { + binexpr.error( "AD: Bit and expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::equality_expression) = { + binexpr.error( "AD: Equality or expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::relational_expression) = { + binexpr.error( "AD: Relational expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::compare_expression) = { + binexpr.error( "AD: Compare or expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::shift_expression) = { + binexpr.error( "AD: Shift or expressions are not yet handled as standalone statements.." ); + } + + traverse: (override inout this, binexpr: meta::additive_expression) = { + binexpr.error( "AD: Additive expressions are not yet handled as standalone statements." ); + } + + traverse: (override inout this, binexpr: meta::multiplicative_expression) = { + binexpr.error( "AD: Multiplicative expressions are not yet handled as standalone statements." ); + } + + traverse: (override inout this, isas: meta::is_as_expression) = { + isas.error( "AD: Is as expressions are not yet handled as standalone statements." ); + } + + traverse: (override inout this, prefix: meta::prefix_expression) = + { + prefix.error( "AD: Prefix expressions are not yet handled as standalone statements." ); + } + + traverse: (override inout this, postfix: meta::postfix_expression) = + { + // TODO: Unify with autodiff_expression_handler implementation + terms := postfix.get_terms(); + + is_func := true; + + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + continue; + } + if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + continue; + } + + is_func = false; + } + + // Check for function call, everything else is not handled. + if !(is_func) { + postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); + return; + } + + object : std::string = ""; + object_d : std::string = ""; + function_name : std::string = ""; + args : std::vector = (); + + primary := postfix.get_primary_expression(); + + + if 1 != terms.ssize() { + object = primary.to_string(); + object_d = primary.to_string() + "_d"; + } + else { + function_name = primary.to_string(); + } + + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + assert(term.is_id_expression()); + name := term.get_id_expression().to_string(); + + if i + 2 == terms.ssize() { // Second last term is function name, last term is function argument list + function_name = name; + } + else { + object += "." + name; + object_d += "." + name; + } + } + else if term.get_op() == "(" { + assert(term.is_expression_list()); + + ad: autodiff_expression_handler = (ctx, ""); + args = ad.handle_expression_list(term.get_expression_list()); + append(ad); + } + else { + postfix.error("AD: Do not know how to handle postfix term: (term.to_string())$"); + } } + + if handle_special_function(object, object_d, function_name, args) { + return; + } + + // No special handling, currently only allow direct function calls + if !object.empty() { + postfix.error("AD: Can currently only handle direct function calls and no member function calls.: (postfix.to_string())$"); + } + + // TODO: This is untested. Requires handling of out and inout parameters in functions. + // All arguments have now been handled. Form the function call + diff += "(function_name)$_diff("; + for args do (arg) { + diff += "(arg)$, (arg)$_d,"; + } + diff += ");\n"; + + } + + traverse: (override inout this, primary: meta::primary_expression) = + { + primary.error( "AD: Primary expressions are not yet handled as standalone statements." ); } } From f1b5de78f34a5581a7d91620e5c98f07645c05c1 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 11:54:56 +0200 Subject: [PATCH 16/54] Unified function call handling. --- source/reflect.h | 1270 +++++++++++++++++++++++---------------------- source/reflect.h2 | 270 +++++----- 2 files changed, 810 insertions(+), 730 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index e079c6e95..f52af5be0 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -117,80 +117,80 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4273 "reflect.h2" +#line 4390 "reflect.h2" class autodiff_stmt_handler; -#line 5058 "reflect.h2" +#line 5092 "reflect.h2" class expression_flags; -#line 5074 "reflect.h2" +#line 5108 "reflect.h2" class regex_token; -#line 5101 "reflect.h2" +#line 5135 "reflect.h2" class regex_token_check; -#line 5122 "reflect.h2" +#line 5156 "reflect.h2" class regex_token_code; -#line 5143 "reflect.h2" +#line 5177 "reflect.h2" class regex_token_empty; -#line 5161 "reflect.h2" +#line 5195 "reflect.h2" class regex_token_list; -#line 5213 "reflect.h2" +#line 5247 "reflect.h2" class parse_context_group_state; -#line 5274 "reflect.h2" +#line 5308 "reflect.h2" class parse_context_branch_reset_state; -#line 5317 "reflect.h2" +#line 5351 "reflect.h2" class parse_context; -#line 5718 "reflect.h2" +#line 5752 "reflect.h2" class generation_function_context; -#line 5736 "reflect.h2" +#line 5770 "reflect.h2" class generation_context; -#line 5935 "reflect.h2" +#line 5969 "reflect.h2" class alternative_token; -#line 5950 "reflect.h2" +#line 5984 "reflect.h2" class alternative_token_gen; -#line 6015 "reflect.h2" +#line 6049 "reflect.h2" class any_token; -#line 6032 "reflect.h2" +#line 6066 "reflect.h2" class atomic_group_token; -#line 6062 "reflect.h2" +#line 6096 "reflect.h2" class char_token; -#line 6177 "reflect.h2" +#line 6211 "reflect.h2" class class_token; -#line 6401 "reflect.h2" +#line 6435 "reflect.h2" class group_ref_token; -#line 6538 "reflect.h2" +#line 6572 "reflect.h2" class group_token; -#line 6885 "reflect.h2" +#line 6919 "reflect.h2" class lookahead_lookbehind_token; -#line 6980 "reflect.h2" +#line 7014 "reflect.h2" class range_token; -#line 7137 "reflect.h2" +#line 7171 "reflect.h2" class special_range_token; -#line 7223 "reflect.h2" +#line 7257 "reflect.h2" template class regex_generator; -#line 7480 "reflect.h2" +#line 7514 "reflect.h2" } } @@ -1690,170 +1690,173 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; #line 4076 "reflect.h2" + public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; + +#line 4177 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 4090 "reflect.h2" +#line 4191 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; + +#line 4224 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4094 "reflect.h2" +#line 4228 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4098 "reflect.h2" +#line 4232 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4102 "reflect.h2" +#line 4236 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4106 "reflect.h2" +#line 4240 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4110 "reflect.h2" +#line 4244 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4114 "reflect.h2" +#line 4248 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4118 "reflect.h2" +#line 4252 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4122 "reflect.h2" +#line 4256 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4126 "reflect.h2" +#line 4260 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4130 "reflect.h2" +#line 4264 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4134 "reflect.h2" +#line 4268 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4157 "reflect.h2" +#line 4291 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4200 "reflect.h2" +#line 4334 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4204 "reflect.h2" +#line 4338 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4209 "reflect.h2" +#line 4343 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4253 "reflect.h2" +#line 4370 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4271 "reflect.h2" +#line 4388 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4277 "reflect.h2" +#line 4394 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4286 "reflect.h2" - public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; - -#line 4312 "reflect.h2" +#line 4403 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4317 "reflect.h2" +#line 4408 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4322 "reflect.h2" +#line 4413 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4335 "reflect.h2" +#line 4426 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4340 "reflect.h2" +#line 4431 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4345 "reflect.h2" +#line 4436 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4350 "reflect.h2" +#line 4441 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4358 "reflect.h2" +#line 4449 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4374 "reflect.h2" +#line 4465 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4421 "reflect.h2" +#line 4512 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4432 "reflect.h2" +#line 4523 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4460 "reflect.h2" +#line 4551 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4465 "reflect.h2" +#line 4556 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4469 "reflect.h2" +#line 4560 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4473 "reflect.h2" +#line 4564 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4477 "reflect.h2" +#line 4568 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4481 "reflect.h2" +#line 4572 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4485 "reflect.h2" +#line 4576 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4489 "reflect.h2" +#line 4580 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4493 "reflect.h2" +#line 4584 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4497 "reflect.h2" +#line 4588 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4501 "reflect.h2" +#line 4592 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4505 "reflect.h2" +#line 4596 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4509 "reflect.h2" +#line 4600 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4513 "reflect.h2" +#line 4604 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4518 "reflect.h2" +#line 4609 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4604 "reflect.h2" +#line 4638 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4608 "reflect.h2" +#line 4642 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 5054 "reflect.h2" +#line 5088 "reflect.h2" using error_func = std::function x)>; -#line 5058 "reflect.h2" +#line 5092 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1888,20 +1891,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5066 "reflect.h2" +#line 5100 "reflect.h2" }; -#line 5074 "reflect.h2" +#line 5108 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5082 "reflect.h2" +#line 5116 "reflect.h2" public: explicit regex_token(); -#line 5087 "reflect.h2" +#line 5121 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1913,103 +1916,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5093 "reflect.h2" +#line 5127 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5099 "reflect.h2" +#line 5133 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5105 "reflect.h2" +#line 5139 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5112 "reflect.h2" +#line 5146 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5116 "reflect.h2" +#line 5150 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5117 "reflect.h2" +#line 5151 "reflect.h2" }; -#line 5120 "reflect.h2" +#line 5154 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5126 "reflect.h2" +#line 5160 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5133 "reflect.h2" +#line 5167 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5137 "reflect.h2" +#line 5171 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5138 "reflect.h2" +#line 5172 "reflect.h2" }; -#line 5141 "reflect.h2" +#line 5175 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5147 "reflect.h2" +#line 5181 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5151 "reflect.h2" +#line 5185 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5155 "reflect.h2" +#line 5189 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5156 "reflect.h2" +#line 5190 "reflect.h2" }; -#line 5159 "reflect.h2" +#line 5193 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5165 "reflect.h2" +#line 5199 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5172 "reflect.h2" +#line 5206 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5178 "reflect.h2" +#line 5212 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5184 "reflect.h2" +#line 5218 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5192 "reflect.h2" +#line 5226 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2017,10 +2020,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5204 "reflect.h2" +#line 5238 "reflect.h2" }; -#line 5207 "reflect.h2" +#line 5241 "reflect.h2" // // Parse and generation context. // @@ -2036,33 +2039,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5227 "reflect.h2" +#line 5261 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5234 "reflect.h2" +#line 5268 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5246 "reflect.h2" +#line 5280 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5251 "reflect.h2" +#line 5285 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5255 "reflect.h2" +#line 5289 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5269 "reflect.h2" +#line 5303 "reflect.h2" }; -#line 5272 "reflect.h2" +#line 5306 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2075,25 +2078,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5290 "reflect.h2" +#line 5324 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5296 "reflect.h2" +#line 5330 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5303 "reflect.h2" +#line 5337 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5310 "reflect.h2" +#line 5344 "reflect.h2" }; -#line 5313 "reflect.h2" +#line 5347 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2109,7 +2112,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5329 "reflect.h2" +#line 5363 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2117,64 +2120,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5340 "reflect.h2" +#line 5374 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5353 "reflect.h2" +#line 5387 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5361 "reflect.h2" +#line 5395 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5365 "reflect.h2" +#line 5399 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5369 "reflect.h2" +#line 5403 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5381 "reflect.h2" +#line 5415 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5388 "reflect.h2" +#line 5422 "reflect.h2" public: auto next_alternative() & -> void; -#line 5394 "reflect.h2" +#line 5428 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5400 "reflect.h2" +#line 5434 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5404 "reflect.h2" +#line 5438 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5415 "reflect.h2" +#line 5449 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5419 "reflect.h2" +#line 5453 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5425 "reflect.h2" +#line 5459 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5429 "reflect.h2" +#line 5463 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5436 "reflect.h2" +#line 5470 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5447 "reflect.h2" +#line 5481 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2182,51 +2185,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5491 "reflect.h2" +#line 5525 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5503 "reflect.h2" +#line 5537 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5516 "reflect.h2" +#line 5550 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5539 "reflect.h2" +#line 5573 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5556 "reflect.h2" +#line 5590 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5577 "reflect.h2" +#line 5611 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5587 "reflect.h2" +#line 5621 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5591 "reflect.h2" +#line 5625 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5647 "reflect.h2" +#line 5681 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5686 "reflect.h2" +#line 5720 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5701 "reflect.h2" +#line 5735 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2238,10 +2241,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5712 "reflect.h2" +#line 5746 "reflect.h2" }; -#line 5715 "reflect.h2" +#line 5749 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2251,16 +2254,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5729 "reflect.h2" +#line 5763 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5732 "reflect.h2" +#line 5766 "reflect.h2" }; -#line 5735 "reflect.h2" +#line 5769 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2280,68 +2283,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5757 "reflect.h2" +#line 5791 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5763 "reflect.h2" +#line 5797 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5772 "reflect.h2" +#line 5806 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5783 "reflect.h2" +#line 5817 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5790 "reflect.h2" +#line 5824 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5810 "reflect.h2" +#line 5844 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5820 "reflect.h2" +#line 5854 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5843 "reflect.h2" +#line 5877 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5851 "reflect.h2" +#line 5885 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5855 "reflect.h2" +#line 5889 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5861 "reflect.h2" +#line 5895 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5867 "reflect.h2" +#line 5901 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5877 "reflect.h2" +#line 5911 "reflect.h2" public: auto finish_context() & -> void; -#line 5885 "reflect.h2" +#line 5919 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5891 "reflect.h2" +#line 5925 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5895 "reflect.h2" +#line 5929 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5899 "reflect.h2" +#line 5933 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5923 "reflect.h2" +#line 5957 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2349,7 +2352,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5929 "reflect.h2" +#line 5963 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2369,27 +2372,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5948 "reflect.h2" +#line 5982 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5954 "reflect.h2" +#line 5988 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5961 "reflect.h2" +#line 5995 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5978 "reflect.h2" +#line 6012 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5985 "reflect.h2" +#line 6019 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5998 "reflect.h2" +#line 6032 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2397,19 +2400,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6010 "reflect.h2" +#line 6044 "reflect.h2" }; -#line 6013 "reflect.h2" +#line 6047 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6019 "reflect.h2" +#line 6053 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6023 "reflect.h2" +#line 6057 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2417,7 +2420,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6028 "reflect.h2" +#line 6062 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2425,17 +2428,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6036 "reflect.h2" +#line 6070 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6047 "reflect.h2" +#line 6081 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6055 "reflect.h2" +#line 6089 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2443,7 +2446,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6058 "reflect.h2" +#line 6092 "reflect.h2" }; // Regex syntax: a @@ -2451,34 +2454,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6066 "reflect.h2" +#line 6100 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6075 "reflect.h2" +#line 6109 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6081 "reflect.h2" +#line 6115 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6085 "reflect.h2" +#line 6119 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6108 "reflect.h2" +#line 6142 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6129 "reflect.h2" +#line 6163 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6147 "reflect.h2" +#line 6181 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6162 "reflect.h2" +#line 6196 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6168 "reflect.h2" +#line 6202 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2486,33 +2489,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6172 "reflect.h2" +#line 6206 "reflect.h2" }; -#line 6175 "reflect.h2" +#line 6209 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6181 "reflect.h2" +#line 6215 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6193 "reflect.h2" +#line 6227 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6319 "reflect.h2" +#line 6353 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6328 "reflect.h2" +#line 6362 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6333 "reflect.h2" +#line 6367 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2520,20 +2523,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6340 "reflect.h2" +#line 6374 "reflect.h2" }; -#line 6343 "reflect.h2" +#line 6377 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6384 "reflect.h2" +#line 6418 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6395 "reflect.h2" +#line 6429 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2543,20 +2546,20 @@ class class_token class group_ref_token : public regex_token { -#line 6405 "reflect.h2" +#line 6439 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6417 "reflect.h2" +#line 6451 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6518 "reflect.h2" +#line 6552 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6522 "reflect.h2" +#line 6556 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2564,10 +2567,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6525 "reflect.h2" +#line 6559 "reflect.h2" }; -#line 6528 "reflect.h2" +#line 6562 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2581,29 +2584,29 @@ class group_ref_token class group_token : public regex_token { -#line 6542 "reflect.h2" +#line 6576 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6564 "reflect.h2" +#line 6598 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6578 "reflect.h2" +#line 6612 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6737 "reflect.h2" +#line 6771 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6745 "reflect.h2" +#line 6779 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6763 "reflect.h2" +#line 6797 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6794 "reflect.h2" +#line 6828 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2612,25 +2615,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6801 "reflect.h2" +#line 6835 "reflect.h2" }; -#line 6804 "reflect.h2" +#line 6838 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6845 "reflect.h2" +#line 6879 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6865 "reflect.h2" +#line 6899 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6881 "reflect.h2" +#line 6915 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2638,20 +2641,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6889 "reflect.h2" +#line 6923 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6898 "reflect.h2" +#line 6932 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6909 "reflect.h2" +#line 6943 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6916 "reflect.h2" +#line 6950 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2659,26 +2662,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6919 "reflect.h2" +#line 6953 "reflect.h2" }; -#line 6922 "reflect.h2" +#line 6956 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6950 "reflect.h2" +#line 6984 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6978 "reflect.h2" +#line 7012 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6984 "reflect.h2" +#line 7018 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2688,22 +2691,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7064 "reflect.h2" +#line 7098 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7076 "reflect.h2" +#line 7110 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7089 "reflect.h2" +#line 7123 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7108 "reflect.h2" +#line 7142 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7118 "reflect.h2" +#line 7152 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7129 "reflect.h2" +#line 7163 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2711,16 +2714,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7132 "reflect.h2" +#line 7166 "reflect.h2" }; -#line 7135 "reflect.h2" +#line 7169 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7141 "reflect.h2" +#line 7175 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2729,7 +2732,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7171 "reflect.h2" +#line 7205 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2738,14 +2741,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7193 "reflect.h2" +#line 7227 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7215 "reflect.h2" +#line 7249 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2766,24 +2769,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7238 "reflect.h2" +#line 7272 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7273 "reflect.h2" +#line 7307 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7287 "reflect.h2" +#line 7321 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7299 "reflect.h2" +#line 7333 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7354 "reflect.h2" +#line 7388 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2794,7 +2797,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7480 "reflect.h2" +#line 7514 "reflect.h2" } } @@ -7492,6 +7495,116 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } #line 4076 "reflect.h2" + auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + auto is_func {true}; +{ +auto i{0}; + +#line 4082 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + continue; + } + if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + continue; + } + + is_func = false; + } while (false); i += 1; } +} + + // Check for function call, everything else is not handled. +#line 4094 "reflect.h2" + if (!((cpp2::move(is_func)))) { + CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + return ; + } + + std::string object {""}; + std::string object_d {""}; + std::string function_name {""}; + std::vector args {}; + + auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; + + if (1 != CPP2_UFCS(ssize)(terms)) { + object = CPP2_UFCS(to_string)(primary); + object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + "_d"; + } + else { + function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); + } +{ +auto i{0}; + +#line 4115 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } + auto name {CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term))}; + + if (i + 2 == CPP2_UFCS(ssize)(terms)) {// Second last term is function name, last term is function argument list + function_name = cpp2::move(name); + } + else { + object += "." + name; + object_d += "." + cpp2::move(name); + } + } + else {if (CPP2_UFCS(get_op)(term) == "(") { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_expression_list)(term)) ) { cpp2::cpp2_default.report_violation(""); } + + args = handle_expression_list(CPP2_UFCS(get_expression_list)(term)); + } + else { + CPP2_UFCS(error)(postfix, "AD: Do not know how to handle postfix term: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + ""); + }} + } while (false); i += 1; } +} + +#line 4138 "reflect.h2" + auto r_arg {lhs}; + if (!(has_return)) { + r_arg = ""; + } + if (handle_special_function(object, cpp2::move(object_d), function_name, args, cpp2::move(r_arg))) { + return ; + } + // TODO: Extend to a generalized version and not only functions with one argument. + if (handle_math_func(function_name, CPP2_ASSERT_IN_BOUNDS_LITERAL(args, 0))) { + return ; + } + + // No special handling, currently only allow direct function calls + if (!(CPP2_UFCS(empty)(cpp2::move(object)))) { + CPP2_UFCS(error)(postfix, "AD: Can currently only handle direct function calls and no member function calls.: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + } + + // All arguments have now been handled. Form the function call + std::string ret_temp {""}; + if (has_return) { + ret_temp = CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx))); + diff += "" + cpp2::to_string(ret_temp) + " := "; + } + + // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. + diff += "" + cpp2::to_string(cpp2::move(function_name)) + "_diff("; + for ( auto const& arg : cpp2::move(args) ) { + diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; + } + diff += ");\n"; + + if (has_return) { + // TODO: Look up return value name of function. + gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r_d", true);/* switch order = */ + } + + // TODO: Add function to list of functions/objects for differentiation. + } + +#line 4177 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7506,62 +7619,100 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return true; } -#line 4090 "reflect.h2" +#line 4191 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ + + auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; + + if (!(r.m)) { + return false; // No match + } + + // Have a match, do the replacement + std::string code {""}; + code = cpp2::move(r).code;// TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + + if (!(CPP2_UFCS(empty)(object))) { + code = string_util::replace_all(code, "_o_", object); + code = string_util::replace_all(code, "_od_", object_d); + } + + if (!(CPP2_UFCS(empty)(ret))) { + code = string_util::replace_all(code, "_r_", ret); + code = string_util::replace_all(code, "_rd_", ret + "_d"); + } +{ +auto i{1}; + +#line 4214 "reflect.h2" + for ( auto const& arg : args ) { + code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); + code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); + } +} + +#line 4219 "reflect.h2" + diff += cpp2::move(code); + + return true; + } + +#line 4224 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4094 "reflect.h2" +#line 4228 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4098 "reflect.h2" +#line 4232 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4102 "reflect.h2" +#line 4236 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4106 "reflect.h2" +#line 4240 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4110 "reflect.h2" +#line 4244 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4114 "reflect.h2" +#line 4248 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4118 "reflect.h2" +#line 4252 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4122 "reflect.h2" +#line 4256 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4126 "reflect.h2" +#line 4260 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4130 "reflect.h2" +#line 4264 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4134 "reflect.h2" +#line 4268 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7585,7 +7736,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4157 "reflect.h2" +#line 4291 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7612,7 +7763,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4184 "reflect.h2" +#line 4318 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7629,63 +7780,50 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4200 "reflect.h2" +#line 4334 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4204 "reflect.h2" +#line 4338 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4209 "reflect.h2" +#line 4343 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; - // Check for function call, everything else is not handled. - if (CPP2_UFCS(ssize)(terms) != 1 && CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)) != "(") { - CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); - return ; - } + auto is_func {true}; +{ +auto i{0}; - auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; - auto func_name {CPP2_UFCS(to_string)(cpp2::move(primary))}; +#line 4350 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + continue; + } + if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + continue; + } - // First handle all arguments - auto term {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(terms), 0)}; - std::vector args {}; - if (CPP2_UFCS(is_expression_list)(term)) { - args = handle_expression_list(CPP2_UFCS(get_expression_list)(cpp2::move(term))); - } - else { - CPP2_UFCS(push_back)(args, handle_expression_term(CPP2_UFCS(get_expression)(cpp2::move(term)))); - } + is_func = false; + } while (false); i += 1; } +} - // Check if this is a special function, with a user defined handling. - // TODO: Extend to a generalized version and not only functions with one argument. - if (handle_math_func(func_name, CPP2_ASSERT_IN_BOUNDS_LITERAL(args, 0))) { + // Check for function call, everything else is not handled. +#line 4362 "reflect.h2" + if (!((cpp2::move(is_func)))) { + CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; } - // All arguments have now been handled. Form the function call - auto ret_temp {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - diff += "" + cpp2::to_string(ret_temp) + " := " + cpp2::to_string(cpp2::move(func_name)) + "_diff("; - for ( auto const& arg : cpp2::move(args) ) { - diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; - } - diff += ");\n"; - - // Copy the return values - // TODO: Look up return value name of function. - gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r_d", true); - - // TODO: Add function to list of functions/objects for differentiation. + handle_function_call(postfix, true); } -#line 4253 "reflect.h2" +#line 4370 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7705,57 +7843,26 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}}} } -#line 4281 "reflect.h2" +#line 4398 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4284 "reflect.h2" - } - -#line 4286 "reflect.h2" - [[nodiscard]] auto autodiff_stmt_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ - - auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), false, !(CPP2_UFCS(empty)(object)))}; - - if (!(r.m)) { - return false; // No match - } - - // Have a match, do the replacement - std::string code {""}; - code = cpp2::move(r).code;// TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ - - code = string_util::replace_all(code, "_o_", object); - code = string_util::replace_all(code, "_od_", object_d); -{ -auto i{1}; - -#line 4302 "reflect.h2" - for ( auto const& arg : args ) { - code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); - code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); - } -} - -#line 4307 "reflect.h2" - diff += cpp2::move(code); - - return true; +#line 4401 "reflect.h2" } -#line 4312 "reflect.h2" +#line 4403 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4317 "reflect.h2" +#line 4408 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4322 "reflect.h2" +#line 4413 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ auto lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7768,22 +7875,22 @@ auto i{1}; diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + " = " + cpp2::to_string(cpp2::move(init)) + ";\n"; } -#line 4335 "reflect.h2" +#line 4426 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4340 "reflect.h2" +#line 4431 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4345 "reflect.h2" +#line 4436 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4350 "reflect.h2" +#line 4441 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7791,7 +7898,7 @@ auto i{1}; diff += "}\n"; } -#line 4358 "reflect.h2" +#line 4449 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7807,7 +7914,7 @@ auto i{1}; } } -#line 4374 "reflect.h2" +#line 4465 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -7854,7 +7961,7 @@ auto i{1}; }} } -#line 4421 "reflect.h2" +#line 4512 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7866,7 +7973,7 @@ auto i{1}; } } -#line 4432 "reflect.h2" +#line 4523 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -7895,89 +8002,88 @@ auto i{1}; } } -#line 4460 "reflect.h2" +#line 4551 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4465 "reflect.h2" +#line 4556 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4469 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4473 "reflect.h2" +#line 4564 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4477 "reflect.h2" +#line 4568 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4481 "reflect.h2" +#line 4572 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4485 "reflect.h2" +#line 4576 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4489 "reflect.h2" +#line 4580 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4493 "reflect.h2" +#line 4584 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4497 "reflect.h2" +#line 4588 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4501 "reflect.h2" +#line 4592 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4505 "reflect.h2" +#line 4596 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4509 "reflect.h2" +#line 4600 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4513 "reflect.h2" +#line 4604 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4518 "reflect.h2" +#line 4609 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { - // TODO: Unify with autodiff_expression_handler implementation auto terms {CPP2_UFCS(get_terms)(postfix)}; auto is_func {true}; { auto i{0}; -#line 4526 "reflect.h2" +#line 4616 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7991,84 +8097,24 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4538 "reflect.h2" +#line 4628 "reflect.h2" if (!((cpp2::move(is_func)))) { - CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; } - std::string object {""}; - std::string object_d {""}; - std::string function_name {""}; - std::vector args {}; - - auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; - -#line 4551 "reflect.h2" - if (1 != CPP2_UFCS(ssize)(terms)) { - object = CPP2_UFCS(to_string)(primary); - object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + "_d"; - } - else { - function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); - } -{ -auto i{0}; - -#line 4560 "reflect.h2" - for ( auto const& term : terms ) { do { - if (CPP2_UFCS(get_op)(term) == ".") { - if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } - auto name {CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term))}; - - if (i + 2 == CPP2_UFCS(ssize)(terms)) {// Second last term is function name, last term is function argument list - function_name = cpp2::move(name); - } - else { - object += "." + name; - object_d += "." + cpp2::move(name); - } - } - else {if (CPP2_UFCS(get_op)(term) == "(") { - if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_expression_list)(term)) ) { cpp2::cpp2_default.report_violation(""); } - - autodiff_expression_handler ad {ctx, ""}; - args = CPP2_UFCS(handle_expression_list)(ad, CPP2_UFCS(get_expression_list)(term)); - append(cpp2::move(ad)); - } - else { - CPP2_UFCS(error)(postfix, "AD: Do not know how to handle postfix term: " + cpp2::to_string(CPP2_UFCS(to_string)(term)) + ""); - }} - } while (false); i += 1; } -} - -#line 4585 "reflect.h2" - if (handle_special_function(object, cpp2::move(object_d), function_name, args)) { - return ; - } - - // No special handling, currently only allow direct function calls - if (!(CPP2_UFCS(empty)(cpp2::move(object)))) { - CPP2_UFCS(error)(postfix, "AD: Can currently only handle direct function calls and no member function calls.: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); - } - - // TODO: This is untested. Requires handling of out and inout parameters in functions. - // All arguments have now been handled. Form the function call - diff += "" + cpp2::to_string(cpp2::move(function_name)) + "_diff("; - for ( auto const& arg : cpp2::move(args) ) { - diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; - } - diff += ");\n"; - + autodiff_expression_handler ad {ctx, ""}; + CPP2_UFCS(handle_function_call)(ad, postfix, false); + append(cpp2::move(ad)); } -#line 4604 "reflect.h2" +#line 4638 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4610 "reflect.h2" +#line 4644 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -8120,7 +8166,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4662 "reflect.h2" +#line 4696 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8224,7 +8270,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4675 "reflect.h2" +#line 4709 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8589,7 +8635,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 5040 "reflect.h2" +#line 5074 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8605,11 +8651,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5056 "reflect.h2" +#line 5090 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5060 "reflect.h2" +#line 5094 "reflect.h2" // mod: i // mod: m // mod: s @@ -8617,116 +8663,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5069 "reflect.h2" +#line 5103 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5078 "reflect.h2" +#line 5112 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5080 "reflect.h2" +#line 5114 "reflect.h2" } -#line 5082 "reflect.h2" +#line 5116 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5084 "reflect.h2" +#line 5118 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5090 "reflect.h2" +#line 5124 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5091 "reflect.h2" +#line 5125 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5092 "reflect.h2" +#line 5126 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5107 "reflect.h2" +#line 5141 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5110 "reflect.h2" +#line 5144 "reflect.h2" } -#line 5112 "reflect.h2" +#line 5146 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5116 "reflect.h2" +#line 5150 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5128 "reflect.h2" +#line 5162 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5131 "reflect.h2" +#line 5165 "reflect.h2" } -#line 5133 "reflect.h2" +#line 5167 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5137 "reflect.h2" +#line 5171 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5147 "reflect.h2" +#line 5181 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5149 "reflect.h2" +#line 5183 "reflect.h2" } -#line 5151 "reflect.h2" +#line 5185 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5155 "reflect.h2" +#line 5189 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5167 "reflect.h2" +#line 5201 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5170 "reflect.h2" +#line 5204 "reflect.h2" } -#line 5172 "reflect.h2" +#line 5206 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5178 "reflect.h2" +#line 5212 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5184 "reflect.h2" +#line 5218 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8735,7 +8781,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5192 "reflect.h2" +#line 5226 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8751,7 +8797,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5220 "reflect.h2" +#line 5254 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8759,14 +8805,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5228 "reflect.h2" +#line 5262 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5235 "reflect.h2" +#line 5269 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8778,15 +8824,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5247 "reflect.h2" +#line 5281 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5252 "reflect.h2" +#line 5286 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5256 "reflect.h2" +#line 5290 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8807,7 +8853,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5282 "reflect.h2" +#line 5316 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8816,20 +8862,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5291 "reflect.h2" +#line 5325 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5297 "reflect.h2" +#line 5331 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5304 "reflect.h2" +#line 5338 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8844,16 +8890,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5334 "reflect.h2" +#line 5368 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5338 "reflect.h2" +#line 5372 "reflect.h2" } -#line 5344 "reflect.h2" +#line 5378 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8863,7 +8909,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5354 "reflect.h2" +#line 5388 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8871,17 +8917,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5361 "reflect.h2" +#line 5395 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5365 "reflect.h2" +#line 5399 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5372 "reflect.h2" +#line 5406 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8891,7 +8937,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5381 "reflect.h2" +#line 5415 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8899,24 +8945,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5388 "reflect.h2" +#line 5422 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5396 "reflect.h2" +#line 5430 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5400 "reflect.h2" +#line 5434 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5404 "reflect.h2" +#line 5438 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8928,22 +8974,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5415 "reflect.h2" +#line 5449 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5421 "reflect.h2" +#line 5455 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5425 "reflect.h2" +#line 5459 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5429 "reflect.h2" +#line 5463 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8951,7 +8997,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5436 "reflect.h2" +#line 5470 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8963,10 +9009,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5449 "reflect.h2" +#line 5483 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5452 "reflect.h2" +#line 5486 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9006,7 +9052,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5492 "reflect.h2" +#line 5526 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9018,14 +9064,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5503 "reflect.h2" +#line 5537 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5504 "reflect.h2" +#line 5538 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5505 "reflect.h2" +#line 5539 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5507 "reflect.h2" +#line 5541 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9035,10 +9081,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5516 "reflect.h2" +#line 5550 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5518 "reflect.h2" +#line 5552 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9060,14 +9106,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5539 "reflect.h2" +#line 5573 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5540 "reflect.h2" +#line 5574 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5541 "reflect.h2" +#line 5575 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5543 "reflect.h2" +#line 5577 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9081,7 +9127,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5556 "reflect.h2" +#line 5590 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9103,7 +9149,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5577 "reflect.h2" +#line 5611 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9114,12 +9160,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5587 "reflect.h2" +#line 5621 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5588 "reflect.h2" +#line 5622 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5593 "reflect.h2" +#line 5627 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9174,7 +9220,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5647 "reflect.h2" +#line 5681 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9214,7 +9260,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5686 "reflect.h2" +#line 5720 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9230,21 +9276,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5703 "reflect.h2" +#line 5737 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5704 "reflect.h2" +#line 5738 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5705 "reflect.h2" +#line 5739 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5707 "reflect.h2" +#line 5741 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5722 "reflect.h2" +#line 5756 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9252,7 +9298,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5729 "reflect.h2" +#line 5763 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9262,22 +9308,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5747 "reflect.h2" +#line 5781 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5752 "reflect.h2" +#line 5786 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5758 "reflect.h2" +#line 5792 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5764 "reflect.h2" +#line 5798 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9286,7 +9332,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5772 "reflect.h2" +#line 5806 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9298,7 +9344,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5783 "reflect.h2" +#line 5817 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9306,7 +9352,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5790 "reflect.h2" +#line 5824 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9327,7 +9373,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5811 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9337,7 +9383,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5821 "reflect.h2" +#line 5855 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9360,33 +9406,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5845 "reflect.h2" +#line 5879 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5851 "reflect.h2" +#line 5885 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5855 "reflect.h2" +#line 5889 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5861 "reflect.h2" +#line 5895 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5869 "reflect.h2" +#line 5903 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9395,7 +9441,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5877 "reflect.h2" +#line 5911 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9404,22 +9450,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5887 "reflect.h2" +#line 5921 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5891 "reflect.h2" +#line 5925 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5895 "reflect.h2" +#line 5929 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5899 "reflect.h2" +#line 5933 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9443,18 +9489,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5924 "reflect.h2" +#line 5958 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5939 "reflect.h2" +#line 5973 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5941 "reflect.h2" +#line 5975 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9465,15 +9511,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5956 "reflect.h2" +#line 5990 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5959 "reflect.h2" +#line 5993 "reflect.h2" } -#line 5961 "reflect.h2" +#line 5995 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9491,7 +9537,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5978 "reflect.h2" +#line 6012 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9499,7 +9545,7 @@ generation_function_context::generation_function_context(){} } } -#line 5985 "reflect.h2" +#line 6019 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9513,7 +9559,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5998 "reflect.h2" +#line 6032 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9529,14 +9575,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6019 "reflect.h2" +#line 6053 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6021 "reflect.h2" +#line 6055 "reflect.h2" } -#line 6023 "reflect.h2" +#line 6057 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9545,11 +9591,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6038 "reflect.h2" +#line 6072 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6040 "reflect.h2" +#line 6074 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9557,7 +9603,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6047 "reflect.h2" +#line 6081 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9566,37 +9612,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6055 "reflect.h2" +#line 6089 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6069 "reflect.h2" +#line 6103 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6073 "reflect.h2" +#line 6107 "reflect.h2" } -#line 6075 "reflect.h2" +#line 6109 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6079 "reflect.h2" +#line 6113 "reflect.h2" } -#line 6081 "reflect.h2" +#line 6115 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6085 "reflect.h2" +#line 6119 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9605,14 +9651,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6091 "reflect.h2" +#line 6125 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6096 "reflect.h2" +#line 6130 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9625,7 +9671,7 @@ size_t i{0}; } } -#line 6108 "reflect.h2" +#line 6142 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9647,7 +9693,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6129 "reflect.h2" +#line 6163 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9666,7 +9712,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6147 "reflect.h2" +#line 6181 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9682,14 +9728,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6162 "reflect.h2" +#line 6196 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6168 "reflect.h2" +#line 6202 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9697,19 +9743,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6185 "reflect.h2" +#line 6219 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6186 "reflect.h2" +#line 6220 "reflect.h2" { -#line 6191 "reflect.h2" +#line 6225 "reflect.h2" } -#line 6194 "reflect.h2" +#line 6228 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9835,7 +9881,7 @@ size_t i{0}; ); } -#line 6319 "reflect.h2" +#line 6353 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9845,13 +9891,13 @@ size_t i{0}; ); } -#line 6328 "reflect.h2" +#line 6362 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6333 "reflect.h2" +#line 6367 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9862,12 +9908,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6345 "reflect.h2" +#line 6379 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6350 "reflect.h2" +#line 6384 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9901,7 +9947,7 @@ size_t i{0}; } -#line 6386 "reflect.h2" +#line 6420 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9910,19 +9956,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6409 "reflect.h2" +#line 6443 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6410 "reflect.h2" +#line 6444 "reflect.h2" { -#line 6415 "reflect.h2" +#line 6449 "reflect.h2" } -#line 6417 "reflect.h2" +#line 6451 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10024,19 +10070,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6518 "reflect.h2" +#line 6552 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6522 "reflect.h2" +#line 6556 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6546 "reflect.h2" +#line 6580 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10055,7 +10101,7 @@ size_t i{0}; return r; } -#line 6564 "reflect.h2" +#line 6598 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10070,7 +10116,7 @@ size_t i{0}; return r; } -#line 6578 "reflect.h2" +#line 6612 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10230,7 +10276,7 @@ size_t i{0}; } } -#line 6737 "reflect.h2" +#line 6771 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10239,7 +10285,7 @@ size_t i{0}; return r; } -#line 6745 "reflect.h2" +#line 6779 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10258,7 +10304,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6763 "reflect.h2" +#line 6797 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10290,7 +10336,7 @@ size_t i{0}; } } -#line 6794 "reflect.h2" +#line 6828 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10301,7 +10347,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6806 "reflect.h2" +#line 6840 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10340,7 +10386,7 @@ size_t i{0}; return r; } -#line 6847 "reflect.h2" +#line 6881 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10358,7 +10404,7 @@ size_t i{0}; }} } -#line 6867 "reflect.h2" +#line 6901 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10372,16 +10418,16 @@ size_t i{0}; } } -#line 6893 "reflect.h2" +#line 6927 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6896 "reflect.h2" +#line 6930 "reflect.h2" } -#line 6898 "reflect.h2" +#line 6932 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10393,7 +10439,7 @@ size_t i{0}; } } -#line 6909 "reflect.h2" +#line 6943 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10401,14 +10447,14 @@ size_t i{0}; return r; } -#line 6916 "reflect.h2" +#line 6950 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6924 "reflect.h2" +#line 6958 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10434,7 +10480,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6952 "reflect.h2" +#line 6986 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10460,11 +10506,11 @@ size_t i{0}; return r; } -#line 6989 "reflect.h2" +#line 7023 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6991 "reflect.h2" +#line 7025 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10538,7 +10584,7 @@ size_t i{0}; return nullptr; } -#line 7064 "reflect.h2" +#line 7098 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10551,7 +10597,7 @@ size_t i{0}; }} } -#line 7076 "reflect.h2" +#line 7110 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10565,7 +10611,7 @@ size_t i{0}; }} } -#line 7089 "reflect.h2" +#line 7123 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10585,7 +10631,7 @@ size_t i{0}; return r; } -#line 7108 "reflect.h2" +#line 7142 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10596,7 +10642,7 @@ size_t i{0}; return r; } -#line 7118 "reflect.h2" +#line 7152 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10608,14 +10654,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7129 "reflect.h2" +#line 7163 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7141 "reflect.h2" +#line 7175 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10639,7 +10685,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7165 "reflect.h2" +#line 7199 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10649,7 +10695,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7177 "reflect.h2" +#line 7211 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10665,7 +10711,7 @@ size_t i{0}; } } -#line 7197 "reflect.h2" +#line 7231 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10683,15 +10729,15 @@ size_t i{0}; }} } -#line 7233 "reflect.h2" +#line 7267 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7236 "reflect.h2" +#line 7270 "reflect.h2" } -#line 7238 "reflect.h2" +#line 7272 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10727,7 +10773,7 @@ size_t i{0}; return source; } -#line 7273 "reflect.h2" +#line 7307 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10743,7 +10789,7 @@ size_t i{0}; } } -#line 7289 "reflect.h2" +#line 7323 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10752,7 +10798,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10807,7 +10853,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7358 "reflect.h2" +#line 7392 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10929,7 +10975,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7480 "reflect.h2" +#line 7514 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 58d5de79c..bd1ac1417 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4073,6 +4073,107 @@ autodiff_expression_handler: type = { } } + handle_function_call: (inout this, postfix: meta::postfix_expression, has_return: bool) = { + terms := postfix.get_terms(); + + is_func := true; + + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + continue; + } + if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + continue; + } + + is_func = false; + } + + // Check for function call, everything else is not handled. + if !(is_func) { + postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); + return; + } + + object : std::string = ""; + object_d : std::string = ""; + function_name : std::string = ""; + args : std::vector = (); + + primary := postfix.get_primary_expression(); + + if 1 != terms.ssize() { + object = primary.to_string(); + object_d = primary.to_string() + "_d"; + } + else { + function_name = primary.to_string(); + } + + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + assert(term.is_id_expression()); + name := term.get_id_expression().to_string(); + + if i + 2 == terms.ssize() { // Second last term is function name, last term is function argument list + function_name = name; + } + else { + object += "." + name; + object_d += "." + name; + } + } + else if term.get_op() == "(" { + assert(term.is_expression_list()); + + args = handle_expression_list(term.get_expression_list()); + } + else { + postfix.error("AD: Do not know how to handle postfix term: (term.to_string())$"); + } + } + + r_arg := lhs; + if !has_return { + r_arg = ""; + } + if handle_special_function(object, object_d, function_name, args, r_arg) { + return; + } + // TODO: Extend to a generalized version and not only functions with one argument. + if handle_math_func(function_name, args[0]) { + return; + } + + // No special handling, currently only allow direct function calls + if !object.empty() { + postfix.error("AD: Can currently only handle direct function calls and no member function calls.: (postfix.to_string())$"); + } + + // All arguments have now been handled. Form the function call + ret_temp : std::string = ""; + if has_return { + ret_temp = ctx*.gen_temporary(); + diff += "(ret_temp)$ := "; + } + + // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. + diff += "(function_name)$_diff("; + for args do (arg) { + diff += "(arg)$, (arg)$_d,"; + } + diff += ");\n"; + + if has_return { + // TODO: Look up return value name of function. + gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r_d", /* switch order = */ true); + } + + // TODO: Add function to list of functions/objects for differentiation. + } + handle_math_func :(inout this, func_name: std::string, arg: std::string) -> bool = { pos := ctx*.math_funcs.find(func_name); @@ -4087,6 +4188,39 @@ autodiff_expression_handler: type = { return true; } + handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector, ret: std::string) -> bool = { + + r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !ret.empty(), !object.empty()); + + if !r.m { + return false; // No match + } + + // Have a match, do the replacement + code: std::string = ""; + code = r.code; // TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + + if !object.empty() { + code = string_util::replace_all(code, "_o_", object); + code = string_util::replace_all(code, "_od_", object_d); + } + + if !ret.empty() { + code = string_util::replace_all(code, "_r_", ret); + code = string_util::replace_all(code, "_rd_", ret + "_d"); + } + + (copy i := 1) + for args do (arg) { + code = string_util::replace_all(code, "_a(i)$_", arg); + code = string_util::replace_all(code, "_ad(i)$_", arg + "_d"); + } + + diff += code; + + return true; + } + traverse: (override inout this, expr: meta::expression) = { base::traverse(expr); } @@ -4210,44 +4344,27 @@ autodiff_expression_handler: type = { { terms := postfix.get_terms(); - // Check for function call, everything else is not handled. - if terms.ssize() != 1 && terms[0].get_op() != "(" { - postfix.error( "AD: Postfix expressions are only handled for function calls. Do not know how to handle: (postfix.to_string())$" ); - return; - } + is_func := true; - primary := postfix.get_primary_expression(); - func_name := primary.to_string(); + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + continue; + } + if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + continue; + } - // First handle all arguments - term := terms[0]; - args : std::vector = (); - if term.is_expression_list() { - args = handle_expression_list(term.get_expression_list()); - } - else { - args.push_back(handle_expression_term(term.get_expression())); + is_func = false; } - // Check if this is a special function, with a user defined handling. - // TODO: Extend to a generalized version and not only functions with one argument. - if handle_math_func(func_name, args[0]) { + // Check for function call, everything else is not handled. + if !(is_func) { + postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); return; } - // All arguments have now been handled. Form the function call - ret_temp := ctx*.gen_temporary(); - diff += "(ret_temp)$ := (func_name)$_diff("; - for args do (arg) { - diff += "(arg)$, (arg)$_d,"; - } - diff += ");\n"; - - // Copy the return values - // TODO: Look up return value name of function. - gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r_d", true); - - // TODO: Add function to list of functions/objects for differentiation. + handle_function_call(postfix, true); } traverse: (override inout this, primary: meta::primary_expression) = @@ -4283,32 +4400,6 @@ autodiff_stmt_handler: type = { mf = mf_; } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { - - r := ctx*.lookup_special_function_handling(function_name, args.ssize(), false, !object.empty()); - - if !r.m { - return false; // No match - } - - // Have a match, do the replacement - code: std::string = ""; - code = r.code; // TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ - - code = string_util::replace_all(code, "_o_", object); - code = string_util::replace_all(code, "_od_", object_d); - - (copy i := 1) - for args do (arg) { - code = string_util::replace_all(code, "_a(i)$_", arg); - code = string_util::replace_all(code, "_ad(i)$_", arg + "_d"); - } - - diff += code; - - return true; - } - traverse: (override inout this, decl: meta::declaration) = { base::traverse(decl); } @@ -4517,7 +4608,6 @@ autodiff_stmt_handler: type = { traverse: (override inout this, postfix: meta::postfix_expression) = { - // TODO: Unify with autodiff_expression_handler implementation terms := postfix.get_terms(); is_func := true; @@ -4536,69 +4626,13 @@ autodiff_stmt_handler: type = { // Check for function call, everything else is not handled. if !(is_func) { - postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); + postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); return; } - object : std::string = ""; - object_d : std::string = ""; - function_name : std::string = ""; - args : std::vector = (); - - primary := postfix.get_primary_expression(); - - - if 1 != terms.ssize() { - object = primary.to_string(); - object_d = primary.to_string() + "_d"; - } - else { - function_name = primary.to_string(); - } - - (copy i := 0) - for terms next i += 1 do (term) { - if term.get_op() == "." { - assert(term.is_id_expression()); - name := term.get_id_expression().to_string(); - - if i + 2 == terms.ssize() { // Second last term is function name, last term is function argument list - function_name = name; - } - else { - object += "." + name; - object_d += "." + name; - } - } - else if term.get_op() == "(" { - assert(term.is_expression_list()); - - ad: autodiff_expression_handler = (ctx, ""); - args = ad.handle_expression_list(term.get_expression_list()); - append(ad); - } - else { - postfix.error("AD: Do not know how to handle postfix term: (term.to_string())$"); - } - } - - if handle_special_function(object, object_d, function_name, args) { - return; - } - - // No special handling, currently only allow direct function calls - if !object.empty() { - postfix.error("AD: Can currently only handle direct function calls and no member function calls.: (postfix.to_string())$"); - } - - // TODO: This is untested. Requires handling of out and inout parameters in functions. - // All arguments have now been handled. Form the function call - diff += "(function_name)$_diff("; - for args do (arg) { - diff += "(arg)$, (arg)$_d,"; - } - diff += ");\n"; - + ad: autodiff_expression_handler = (ctx, ""); + ad.handle_function_call(postfix, false); + append(ad); } traverse: (override inout this, primary: meta::primary_expression) = From 6932cde11cabd779b937e2cb8afa0fb10b6fc449 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 13:23:07 +0200 Subject: [PATCH 17/54] Proper handling of initializer expressions. --- regression-tests/pure2-autodiff.cpp2 | 20 +- .../test-results/pure2-autodiff.cpp | 122 +- .../test-results/pure2-autodiff.cpp2.output | 80 +- source/reflect.h | 1041 +++++++++-------- source/reflect.h2 | 38 +- 5 files changed, 735 insertions(+), 566 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 529a36787..76fcfebe3 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -83,8 +83,7 @@ ad_test: @autodiff @print type = { } intermediate_var: (x: double, y: double) -> (r: double) = { - t: double = (); // TODO: change to x initializer when we have access to the initializer expression. - t = x + y; + t: double = x + y; r = t; } @@ -104,6 +103,21 @@ ad_test: @autodiff @print type = { r = t; } + intermediate_default_init: (x: double, y: double) -> (r: double) = { + t: double = (); + t = x + y; + + r = t; + } + + intermediate_no_init: (x: double, y: double) -> (r: double) = { + r = 0.0; // TODO: r has to be initialized before t (create issue or wait for fix) + t: double; + t = x + y; + + r = t; + } + while_loop: (x: double, y: double) -> (r: double) = { i: int = 0; @@ -170,6 +184,8 @@ main: () = { write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_diff(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_diff(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 464e49c83..492fd52f4 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -114,27 +114,37 @@ using intermediate_var_ret = double; using intermediate_passive_var_ret = double; -#line 92 "pure2-autodiff.cpp2" +#line 91 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 100 "pure2-autodiff.cpp2" +#line 99 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; +using intermediate_default_init_ret = double; + + +#line 106 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; +using intermediate_no_init_ret = double; + + +#line 113 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 107 "pure2-autodiff.cpp2" +#line 121 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 116 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 127 "pure2-autodiff.cpp2" +#line 141 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_diff_ret { double r; double r_d; }; @@ -221,6 +231,14 @@ struct intermediate_untyped_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto intermediate_untyped_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_diff_ret; +struct intermediate_default_init_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto intermediate_default_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_diff_ret; + +struct intermediate_no_init_diff_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto intermediate_no_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_diff_ret; + struct while_loop_diff_ret { double r; double r_d; }; public: [[nodiscard]] static auto while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret; @@ -238,12 +256,12 @@ public: [[nodiscard]] static auto for_loop_diff(cpp2::impl::in x, cpp2:: public: auto operator=(ad_test const&) -> void = delete; -#line 140 "pure2-autodiff.cpp2" +#line 154 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 146 "pure2-autodiff.cpp2" +#line 160 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -387,16 +405,15 @@ auto main() -> int; [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; #line 86 "pure2-autodiff.cpp2" - double t {}; // TODO: change to x initializer when we have access to the initializer expression. - t = x + y; + double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 92 "pure2-autodiff.cpp2" +#line 91 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 93 "pure2-autodiff.cpp2" +#line 92 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -404,20 +421,41 @@ auto main() -> int; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 100 "pure2-autodiff.cpp2" +#line 99 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 101 "pure2-autodiff.cpp2" +#line 100 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } +#line 106 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ + cpp2::impl::deferred_init r; #line 107 "pure2-autodiff.cpp2" + double t {}; + t = x + y; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + +#line 113 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ + cpp2::impl::deferred_init r; +#line 114 "pure2-autodiff.cpp2" + r.construct(0.0);// TODO: r has to be initialized before t (create issue or wait for fix) + cpp2::impl::deferred_init t; + t.construct(x + y); + + r.value() = cpp2::move(t.value()); + return std::move(r.value()); } + +#line 121 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 108 "pure2-autodiff.cpp2" +#line 122 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -426,10 +464,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 116 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 117 "pure2-autodiff.cpp2" +#line 131 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -440,10 +478,10 @@ auto main() -> int; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 127 "pure2-autodiff.cpp2" +#line 141 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 128 "pure2-autodiff.cpp2" +#line 142 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -621,11 +659,9 @@ auto temp_1_d {x_d - y_d}; [[nodiscard]] auto ad_test::intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret{ double r {0.0}; double r_d {0.0}; -double t_d {}; +double t_d {x_d + y_d}; - double t {}; - t_d = x_d + y_d; - t = x + y; + double t {x + y}; r_d = cpp2::move(t_d); r = cpp2::move(t); return { std::move(r), std::move(r_d) }; @@ -639,7 +675,7 @@ int i_d {}; int i {}; r_d = x_d + y_d; r = x + y; - i_d = { }; + i_d = 0.0; i = 2; static_cast(cpp2::move(i_d)); static_cast(cpp2::move(i)); @@ -659,10 +695,38 @@ auto t_d {0.0}; return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto ad_test::intermediate_default_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_diff_ret{ + double r {0.0}; + double r_d {0.0}; +double t_d {}; + + double t {}; + t_d = x_d + y_d; + t = x + y; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::intermediate_no_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_diff_ret{ + double r {0.0}; + double r_d {0.0};r_d = 0.0; + r = 0.0; + + cpp2::impl::deferred_init t_d; + + cpp2::impl::deferred_init t; + t_d.construct(x_d + y_d); + t.construct(x + y); + r_d = cpp2::move(t_d.value()); + r = cpp2::move(t.value()); + return { std::move(r), std::move(r_d) }; + } + [[nodiscard]] auto ad_test::while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret{ double r {0.0}; double r_d {0.0}; -int i_d {0}; +int i_d {0.0}; int i {0}; r_d = x_d; @@ -677,7 +741,7 @@ int i_d {0}; [[nodiscard]] auto ad_test::do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret{ double r {0.0}; double r_d {0.0}; -int i_d {0}; +int i_d {0.0}; int i {0}; r_d = x_d; @@ -704,7 +768,7 @@ std::vector v_d {}; CPP2_UFCS(push_back)(v_d, x_d); CPP2_UFCS(push_back)(v, y); CPP2_UFCS(push_back)(v_d, y_d); - r_d = { }; + r_d = 0.0; r = 0.0; { auto t_d_iter{CPP2_UFCS(begin)(cpp2::move(v_d))}; @@ -722,12 +786,12 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 142 "pure2-autodiff.cpp2" +#line 156 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 146 "pure2-autodiff.cpp2" +#line 160 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -755,6 +819,8 @@ auto main() -> int{ write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_diff(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_diff(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 75b420ce7..06311e58b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -179,8 +179,7 @@ ad_test:/* @autodiff @print */ type = in y: double, ) -> (out r: double, ) = { - t: double = (); - t = x + y; + t: double = x + y; r = t; return; } @@ -208,6 +207,29 @@ ad_test:/* @autodiff @print */ type = return; } + intermediate_default_init:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: double = (); + t = x + y; + r = t; + return; + } + + intermediate_no_init:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = 0.0; + t: double; + t = x + y; + r = t; + return; + } + while_loop:( in x: double, in y: double, @@ -567,10 +589,8 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - t_d: double = (); - t: double = (); - t_d = x_d + y_d; - t = x + y; + t_d: double = x_d + y_d; + t: double = x + y; r_d = t_d; r = t; return; @@ -590,7 +610,7 @@ ad_test:/* @autodiff @print */ type = i: int = (); r_d = x_d + y_d; r = x + y; - i_d = (); + i_d = 0.0; i = 2; _ = i_d; _ = i; @@ -616,6 +636,46 @@ ad_test:/* @autodiff @print */ type = return; } + intermediate_default_init_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + t_d: double = (); + t: double = (); + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + + intermediate_no_init_diff:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = 0.0; + r = 0.0; + t_d: double; + t: double; + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + while_loop_diff:( in x: double, in x_d: double, @@ -626,7 +686,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = 0; + i_d: int = 0.0; i: int = 0; r_d = x_d; r = x; @@ -649,7 +709,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = 0; + i_d: int = 0.0; i: int = 0; r_d = x_d; r = x; @@ -679,7 +739,7 @@ ad_test:/* @autodiff @print */ type = v_d.push_back(x_d); v.push_back(y); v_d.push_back(y_d); - r_d = (); + r_d = 0.0; r = 0.0; (copy t_d_iter: _ = v_d.begin(), ) for v diff --git a/source/reflect.h b/source/reflect.h index f52af5be0..19e7b67f1 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -117,80 +117,80 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4390 "reflect.h2" +#line 4399 "reflect.h2" class autodiff_stmt_handler; -#line 5092 "reflect.h2" +#line 5106 "reflect.h2" class expression_flags; -#line 5108 "reflect.h2" +#line 5122 "reflect.h2" class regex_token; -#line 5135 "reflect.h2" +#line 5149 "reflect.h2" class regex_token_check; -#line 5156 "reflect.h2" +#line 5170 "reflect.h2" class regex_token_code; -#line 5177 "reflect.h2" +#line 5191 "reflect.h2" class regex_token_empty; -#line 5195 "reflect.h2" +#line 5209 "reflect.h2" class regex_token_list; -#line 5247 "reflect.h2" +#line 5261 "reflect.h2" class parse_context_group_state; -#line 5308 "reflect.h2" +#line 5322 "reflect.h2" class parse_context_branch_reset_state; -#line 5351 "reflect.h2" +#line 5365 "reflect.h2" class parse_context; -#line 5752 "reflect.h2" +#line 5766 "reflect.h2" class generation_function_context; -#line 5770 "reflect.h2" +#line 5784 "reflect.h2" class generation_context; -#line 5969 "reflect.h2" +#line 5983 "reflect.h2" class alternative_token; -#line 5984 "reflect.h2" +#line 5998 "reflect.h2" class alternative_token_gen; -#line 6049 "reflect.h2" +#line 6063 "reflect.h2" class any_token; -#line 6066 "reflect.h2" +#line 6080 "reflect.h2" class atomic_group_token; -#line 6096 "reflect.h2" +#line 6110 "reflect.h2" class char_token; -#line 6211 "reflect.h2" +#line 6225 "reflect.h2" class class_token; -#line 6435 "reflect.h2" +#line 6449 "reflect.h2" class group_ref_token; -#line 6572 "reflect.h2" +#line 6586 "reflect.h2" class group_token; -#line 6919 "reflect.h2" +#line 6933 "reflect.h2" class lookahead_lookbehind_token; -#line 7014 "reflect.h2" +#line 7028 "reflect.h2" class range_token; -#line 7171 "reflect.h2" +#line 7185 "reflect.h2" class special_range_token; -#line 7257 "reflect.h2" +#line 7271 "reflect.h2" template class regex_generator; -#line 7514 "reflect.h2" +#line 7528 "reflect.h2" } } @@ -1678,185 +1678,185 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: std::string declare_p; public: std::string declare_d; - public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_ = ""); + public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4010 "reflect.h2" +#line 4014 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4029 "reflect.h2" +#line 4033 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4038 "reflect.h2" +#line 4042 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4076 "reflect.h2" +#line 4080 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4177 "reflect.h2" +#line 4181 "reflect.h2" public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; -#line 4191 "reflect.h2" +#line 4195 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4224 "reflect.h2" +#line 4228 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4228 "reflect.h2" +#line 4232 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4232 "reflect.h2" +#line 4236 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4236 "reflect.h2" +#line 4240 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4240 "reflect.h2" +#line 4244 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4244 "reflect.h2" +#line 4248 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4248 "reflect.h2" +#line 4252 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4252 "reflect.h2" +#line 4256 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4256 "reflect.h2" +#line 4260 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4260 "reflect.h2" +#line 4264 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4264 "reflect.h2" +#line 4268 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4268 "reflect.h2" +#line 4272 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4291 "reflect.h2" +#line 4295 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4334 "reflect.h2" +#line 4338 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4338 "reflect.h2" +#line 4342 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4343 "reflect.h2" +#line 4347 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4370 "reflect.h2" +#line 4374 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4388 "reflect.h2" +#line 4397 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4394 "reflect.h2" +#line 4403 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4403 "reflect.h2" +#line 4412 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4408 "reflect.h2" +#line 4417 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4413 "reflect.h2" +#line 4422 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4426 "reflect.h2" +#line 4440 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4431 "reflect.h2" +#line 4445 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4436 "reflect.h2" +#line 4450 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4441 "reflect.h2" +#line 4455 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4449 "reflect.h2" +#line 4463 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4465 "reflect.h2" +#line 4479 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4512 "reflect.h2" +#line 4526 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4523 "reflect.h2" +#line 4537 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4551 "reflect.h2" +#line 4565 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4556 "reflect.h2" +#line 4570 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4560 "reflect.h2" +#line 4574 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4564 "reflect.h2" +#line 4578 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4568 "reflect.h2" +#line 4582 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4572 "reflect.h2" +#line 4586 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4576 "reflect.h2" +#line 4590 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4580 "reflect.h2" +#line 4594 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4584 "reflect.h2" +#line 4598 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4588 "reflect.h2" +#line 4602 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4592 "reflect.h2" +#line 4606 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4596 "reflect.h2" +#line 4610 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4600 "reflect.h2" +#line 4614 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4604 "reflect.h2" +#line 4618 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4609 "reflect.h2" +#line 4623 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4638 "reflect.h2" +#line 4652 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4642 "reflect.h2" +#line 4656 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 5088 "reflect.h2" +#line 5102 "reflect.h2" using error_func = std::function x)>; -#line 5092 "reflect.h2" +#line 5106 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1891,20 +1891,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5100 "reflect.h2" +#line 5114 "reflect.h2" }; -#line 5108 "reflect.h2" +#line 5122 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5116 "reflect.h2" +#line 5130 "reflect.h2" public: explicit regex_token(); -#line 5121 "reflect.h2" +#line 5135 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1916,103 +1916,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5127 "reflect.h2" +#line 5141 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5133 "reflect.h2" +#line 5147 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5139 "reflect.h2" +#line 5153 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5146 "reflect.h2" +#line 5160 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5150 "reflect.h2" +#line 5164 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5151 "reflect.h2" +#line 5165 "reflect.h2" }; -#line 5154 "reflect.h2" +#line 5168 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5160 "reflect.h2" +#line 5174 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5167 "reflect.h2" +#line 5181 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5171 "reflect.h2" +#line 5185 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5172 "reflect.h2" +#line 5186 "reflect.h2" }; -#line 5175 "reflect.h2" +#line 5189 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5181 "reflect.h2" +#line 5195 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5185 "reflect.h2" +#line 5199 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5189 "reflect.h2" +#line 5203 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5190 "reflect.h2" +#line 5204 "reflect.h2" }; -#line 5193 "reflect.h2" +#line 5207 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5199 "reflect.h2" +#line 5213 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5206 "reflect.h2" +#line 5220 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5212 "reflect.h2" +#line 5226 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5218 "reflect.h2" +#line 5232 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5226 "reflect.h2" +#line 5240 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2020,10 +2020,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5238 "reflect.h2" +#line 5252 "reflect.h2" }; -#line 5241 "reflect.h2" +#line 5255 "reflect.h2" // // Parse and generation context. // @@ -2039,33 +2039,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5261 "reflect.h2" +#line 5275 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5268 "reflect.h2" +#line 5282 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5280 "reflect.h2" +#line 5294 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5285 "reflect.h2" +#line 5299 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5289 "reflect.h2" +#line 5303 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5303 "reflect.h2" +#line 5317 "reflect.h2" }; -#line 5306 "reflect.h2" +#line 5320 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2078,25 +2078,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5324 "reflect.h2" +#line 5338 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5330 "reflect.h2" +#line 5344 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5337 "reflect.h2" +#line 5351 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5344 "reflect.h2" +#line 5358 "reflect.h2" }; -#line 5347 "reflect.h2" +#line 5361 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2112,7 +2112,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5363 "reflect.h2" +#line 5377 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2120,64 +2120,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5374 "reflect.h2" +#line 5388 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5387 "reflect.h2" +#line 5401 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5395 "reflect.h2" +#line 5409 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5399 "reflect.h2" +#line 5413 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5403 "reflect.h2" +#line 5417 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5415 "reflect.h2" +#line 5429 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5422 "reflect.h2" +#line 5436 "reflect.h2" public: auto next_alternative() & -> void; -#line 5428 "reflect.h2" +#line 5442 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5434 "reflect.h2" +#line 5448 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5438 "reflect.h2" +#line 5452 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5449 "reflect.h2" +#line 5463 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5453 "reflect.h2" +#line 5467 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5459 "reflect.h2" +#line 5473 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5463 "reflect.h2" +#line 5477 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5470 "reflect.h2" +#line 5484 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5481 "reflect.h2" +#line 5495 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2185,51 +2185,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5525 "reflect.h2" +#line 5539 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5537 "reflect.h2" +#line 5551 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5550 "reflect.h2" +#line 5564 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5573 "reflect.h2" +#line 5587 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5590 "reflect.h2" +#line 5604 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5611 "reflect.h2" +#line 5625 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5621 "reflect.h2" +#line 5635 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5625 "reflect.h2" +#line 5639 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5681 "reflect.h2" +#line 5695 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5720 "reflect.h2" +#line 5734 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5735 "reflect.h2" +#line 5749 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2241,10 +2241,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5746 "reflect.h2" +#line 5760 "reflect.h2" }; -#line 5749 "reflect.h2" +#line 5763 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2254,16 +2254,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5763 "reflect.h2" +#line 5777 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5766 "reflect.h2" +#line 5780 "reflect.h2" }; -#line 5769 "reflect.h2" +#line 5783 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2283,68 +2283,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5791 "reflect.h2" +#line 5805 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5797 "reflect.h2" +#line 5811 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5806 "reflect.h2" +#line 5820 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5817 "reflect.h2" +#line 5831 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5824 "reflect.h2" +#line 5838 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5844 "reflect.h2" +#line 5858 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5854 "reflect.h2" +#line 5868 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5877 "reflect.h2" +#line 5891 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5885 "reflect.h2" +#line 5899 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5889 "reflect.h2" +#line 5903 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5895 "reflect.h2" +#line 5909 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5901 "reflect.h2" +#line 5915 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5911 "reflect.h2" +#line 5925 "reflect.h2" public: auto finish_context() & -> void; -#line 5919 "reflect.h2" +#line 5933 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5925 "reflect.h2" +#line 5939 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5929 "reflect.h2" +#line 5943 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5933 "reflect.h2" +#line 5947 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5957 "reflect.h2" +#line 5971 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2352,7 +2352,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5963 "reflect.h2" +#line 5977 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2372,27 +2372,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5982 "reflect.h2" +#line 5996 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5988 "reflect.h2" +#line 6002 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5995 "reflect.h2" +#line 6009 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6012 "reflect.h2" +#line 6026 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6019 "reflect.h2" +#line 6033 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6032 "reflect.h2" +#line 6046 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2400,19 +2400,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6044 "reflect.h2" +#line 6058 "reflect.h2" }; -#line 6047 "reflect.h2" +#line 6061 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6053 "reflect.h2" +#line 6067 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6057 "reflect.h2" +#line 6071 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2420,7 +2420,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6062 "reflect.h2" +#line 6076 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2428,17 +2428,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6070 "reflect.h2" +#line 6084 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6081 "reflect.h2" +#line 6095 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6089 "reflect.h2" +#line 6103 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2446,7 +2446,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6092 "reflect.h2" +#line 6106 "reflect.h2" }; // Regex syntax: a @@ -2454,34 +2454,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6100 "reflect.h2" +#line 6114 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6109 "reflect.h2" +#line 6123 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6115 "reflect.h2" +#line 6129 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6119 "reflect.h2" +#line 6133 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6142 "reflect.h2" +#line 6156 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6163 "reflect.h2" +#line 6177 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6181 "reflect.h2" +#line 6195 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6196 "reflect.h2" +#line 6210 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6202 "reflect.h2" +#line 6216 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2489,33 +2489,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6206 "reflect.h2" +#line 6220 "reflect.h2" }; -#line 6209 "reflect.h2" +#line 6223 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6215 "reflect.h2" +#line 6229 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6227 "reflect.h2" +#line 6241 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6353 "reflect.h2" +#line 6367 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6362 "reflect.h2" +#line 6376 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6367 "reflect.h2" +#line 6381 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2523,20 +2523,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6374 "reflect.h2" +#line 6388 "reflect.h2" }; -#line 6377 "reflect.h2" +#line 6391 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6418 "reflect.h2" +#line 6432 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6429 "reflect.h2" +#line 6443 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2546,20 +2546,20 @@ class class_token class group_ref_token : public regex_token { -#line 6439 "reflect.h2" +#line 6453 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6451 "reflect.h2" +#line 6465 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6552 "reflect.h2" +#line 6566 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6556 "reflect.h2" +#line 6570 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2567,10 +2567,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6559 "reflect.h2" +#line 6573 "reflect.h2" }; -#line 6562 "reflect.h2" +#line 6576 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2584,29 +2584,29 @@ class group_ref_token class group_token : public regex_token { -#line 6576 "reflect.h2" +#line 6590 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6598 "reflect.h2" +#line 6612 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6612 "reflect.h2" +#line 6626 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6771 "reflect.h2" +#line 6785 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6779 "reflect.h2" +#line 6793 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6797 "reflect.h2" +#line 6811 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6828 "reflect.h2" +#line 6842 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2615,25 +2615,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6835 "reflect.h2" +#line 6849 "reflect.h2" }; -#line 6838 "reflect.h2" +#line 6852 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6879 "reflect.h2" +#line 6893 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6899 "reflect.h2" +#line 6913 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6915 "reflect.h2" +#line 6929 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2641,20 +2641,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6923 "reflect.h2" +#line 6937 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6932 "reflect.h2" +#line 6946 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6943 "reflect.h2" +#line 6957 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6950 "reflect.h2" +#line 6964 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2662,26 +2662,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6953 "reflect.h2" +#line 6967 "reflect.h2" }; -#line 6956 "reflect.h2" +#line 6970 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6984 "reflect.h2" +#line 6998 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7012 "reflect.h2" +#line 7026 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7018 "reflect.h2" +#line 7032 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2691,22 +2691,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7098 "reflect.h2" +#line 7112 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7110 "reflect.h2" +#line 7124 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7123 "reflect.h2" +#line 7137 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7142 "reflect.h2" +#line 7156 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7152 "reflect.h2" +#line 7166 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7163 "reflect.h2" +#line 7177 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2714,16 +2714,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7166 "reflect.h2" +#line 7180 "reflect.h2" }; -#line 7169 "reflect.h2" +#line 7183 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7175 "reflect.h2" +#line 7189 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2732,7 +2732,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7205 "reflect.h2" +#line 7219 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2741,14 +2741,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7227 "reflect.h2" +#line 7241 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7249 "reflect.h2" +#line 7263 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2769,24 +2769,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7272 "reflect.h2" +#line 7286 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7307 "reflect.h2" +#line 7321 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7321 "reflect.h2" +#line 7335 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7333 "reflect.h2" +#line 7347 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7388 "reflect.h2" +#line 7402 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2797,7 +2797,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7514 "reflect.h2" +#line 7528 "reflect.h2" } } @@ -7415,17 +7415,20 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } #line 4003 "reflect.h2" - autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_) + autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , lhs{ lhs_ } - , declare_p{ declare_ } - , declare_d{ declare_ }{ + , declare_p{ declare_p_ } + , declare_d{ declare_d_ }{ -#line 4008 "reflect.h2" +#line 4009 "reflect.h2" + if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { + declare_d = declare_p; + } } -#line 4010 "reflect.h2" +#line 4014 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + "_d"}; if (lhs == "_") { @@ -7445,7 +7448,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4029 "reflect.h2" +#line 4033 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7455,7 +7458,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4038 "reflect.h2" +#line 4042 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7494,7 +7497,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4076 "reflect.h2" +#line 4080 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7502,7 +7505,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4082 "reflect.h2" +#line 4086 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7516,7 +7519,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4094 "reflect.h2" +#line 4098 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7539,7 +7542,7 @@ auto i{0}; { auto i{0}; -#line 4115 "reflect.h2" +#line 4119 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7564,7 +7567,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4138 "reflect.h2" +#line 4142 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7604,7 +7607,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation. } -#line 4177 "reflect.h2" +#line 4181 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; @@ -7619,7 +7622,7 @@ auto i{0}; return true; } -#line 4191 "reflect.h2" +#line 4195 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7644,75 +7647,75 @@ auto i{0}; { auto i{1}; -#line 4214 "reflect.h2" +#line 4218 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); } } -#line 4219 "reflect.h2" +#line 4223 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4224 "reflect.h2" +#line 4228 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4228 "reflect.h2" +#line 4232 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4232 "reflect.h2" +#line 4236 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4236 "reflect.h2" +#line 4240 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4240 "reflect.h2" +#line 4244 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4244 "reflect.h2" +#line 4248 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4248 "reflect.h2" +#line 4252 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4252 "reflect.h2" +#line 4256 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4256 "reflect.h2" +#line 4260 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4260 "reflect.h2" +#line 4264 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4264 "reflect.h2" +#line 4268 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4268 "reflect.h2" +#line 4272 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7736,7 +7739,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4291 "reflect.h2" +#line 4295 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7763,7 +7766,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4318 "reflect.h2" +#line 4322 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7780,18 +7783,18 @@ auto i{1}; } } -#line 4334 "reflect.h2" +#line 4338 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4338 "reflect.h2" +#line 4342 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4343 "reflect.h2" +#line 4347 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7800,7 +7803,7 @@ auto i{1}; { auto i{0}; -#line 4350 "reflect.h2" +#line 4354 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7814,7 +7817,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4362 "reflect.h2" +#line 4366 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7823,17 +7826,22 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4370 "reflect.h2" +#line 4374 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { gen_lhs_assignment(CPP2_UFCS(to_string)(primary), CPP2_UFCS(to_string)(primary) + "_d"); } else {if (CPP2_UFCS(is_expression_list)(primary)) { - CPP2_UFCS(error)(primary, "AD: Do not know how to handle expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { + gen_lhs_assignment("()", "()"); + } + else { + CPP2_UFCS(error)(primary, "AD: Do not know how to handle non empty expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + } } else {if (CPP2_UFCS(is_literal)(primary)) { - gen_lhs_assignment(CPP2_UFCS(to_string)(primary), "()"); + gen_lhs_assignment(CPP2_UFCS(to_string)(primary), "0.0"); } else {if (CPP2_UFCS(is_declaration)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -7843,54 +7851,59 @@ auto i{0}; }}}} } -#line 4398 "reflect.h2" +#line 4407 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4401 "reflect.h2" +#line 4410 "reflect.h2" } -#line 4403 "reflect.h2" +#line 4412 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4408 "reflect.h2" +#line 4417 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4413 "reflect.h2" +#line 4422 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ - auto lhs {CPP2_UFCS(name)(o)}; + std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; - auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type))}; + auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; - // TODO: Get initializer as expression and handle it. - auto init {CPP2_UFCS(initializer)(o)}; - diff += "" + cpp2::to_string(lhs) + "_d : " + cpp2::to_string(ad_type) + " = " + cpp2::to_string(init) + ";\n"; - diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + " = " + cpp2::to_string(cpp2::move(init)) + ";\n"; + if (CPP2_UFCS(has_initializer)(o)) { + autodiff_expression_handler ad {ctx, cpp2::move(lhs), ": " + cpp2::move(type), ": " + cpp2::move(ad_type)}; + CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(o)); + append(cpp2::move(ad)); + } + else { + diff += "" + cpp2::to_string(lhs) + "_d : " + cpp2::to_string(cpp2::move(ad_type)) + ";\n"; + diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + ";\n"; + } } -#line 4426 "reflect.h2" +#line 4440 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4431 "reflect.h2" +#line 4445 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4436 "reflect.h2" +#line 4450 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4441 "reflect.h2" +#line 4455 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7898,7 +7911,7 @@ auto i{0}; diff += "}\n"; } -#line 4449 "reflect.h2" +#line 4463 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7914,7 +7927,7 @@ auto i{0}; } } -#line 4465 "reflect.h2" +#line 4479 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -7961,7 +7974,7 @@ auto i{0}; }} } -#line 4512 "reflect.h2" +#line 4526 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7973,7 +7986,7 @@ auto i{0}; } } -#line 4523 "reflect.h2" +#line 4537 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8002,79 +8015,79 @@ auto i{0}; } } -#line 4551 "reflect.h2" +#line 4565 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4556 "reflect.h2" +#line 4570 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4560 "reflect.h2" +#line 4574 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4564 "reflect.h2" +#line 4578 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4568 "reflect.h2" +#line 4582 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4572 "reflect.h2" +#line 4586 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4576 "reflect.h2" +#line 4590 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4580 "reflect.h2" +#line 4594 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4584 "reflect.h2" +#line 4598 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4588 "reflect.h2" +#line 4602 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4592 "reflect.h2" +#line 4606 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4596 "reflect.h2" +#line 4610 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4600 "reflect.h2" +#line 4614 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4604 "reflect.h2" +#line 4618 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4609 "reflect.h2" +#line 4623 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8083,7 +8096,7 @@ auto i{0}; { auto i{0}; -#line 4616 "reflect.h2" +#line 4630 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8097,7 +8110,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4628 "reflect.h2" +#line 4642 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8108,13 +8121,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4638 "reflect.h2" +#line 4652 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4644 "reflect.h2" +#line 4658 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -8166,7 +8179,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4696 "reflect.h2" +#line 4710 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8270,7 +8283,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4709 "reflect.h2" +#line 4723 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8635,7 +8648,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 5074 "reflect.h2" +#line 5088 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8651,11 +8664,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5090 "reflect.h2" +#line 5104 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5094 "reflect.h2" +#line 5108 "reflect.h2" // mod: i // mod: m // mod: s @@ -8663,116 +8676,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5103 "reflect.h2" +#line 5117 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5112 "reflect.h2" +#line 5126 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5114 "reflect.h2" +#line 5128 "reflect.h2" } -#line 5116 "reflect.h2" +#line 5130 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5118 "reflect.h2" +#line 5132 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5124 "reflect.h2" +#line 5138 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5125 "reflect.h2" +#line 5139 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5126 "reflect.h2" +#line 5140 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5141 "reflect.h2" +#line 5155 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5144 "reflect.h2" +#line 5158 "reflect.h2" } -#line 5146 "reflect.h2" +#line 5160 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5150 "reflect.h2" +#line 5164 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5162 "reflect.h2" +#line 5176 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5165 "reflect.h2" +#line 5179 "reflect.h2" } -#line 5167 "reflect.h2" +#line 5181 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5171 "reflect.h2" +#line 5185 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5181 "reflect.h2" +#line 5195 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5183 "reflect.h2" +#line 5197 "reflect.h2" } -#line 5185 "reflect.h2" +#line 5199 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5189 "reflect.h2" +#line 5203 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5201 "reflect.h2" +#line 5215 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5204 "reflect.h2" +#line 5218 "reflect.h2" } -#line 5206 "reflect.h2" +#line 5220 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5212 "reflect.h2" +#line 5226 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5218 "reflect.h2" +#line 5232 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8781,7 +8794,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5226 "reflect.h2" +#line 5240 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8797,7 +8810,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5254 "reflect.h2" +#line 5268 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8805,14 +8818,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5262 "reflect.h2" +#line 5276 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5269 "reflect.h2" +#line 5283 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8824,15 +8837,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5281 "reflect.h2" +#line 5295 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5286 "reflect.h2" +#line 5300 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5290 "reflect.h2" +#line 5304 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8853,7 +8866,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5316 "reflect.h2" +#line 5330 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8862,20 +8875,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5325 "reflect.h2" +#line 5339 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5331 "reflect.h2" +#line 5345 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5338 "reflect.h2" +#line 5352 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8890,16 +8903,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5368 "reflect.h2" +#line 5382 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5372 "reflect.h2" +#line 5386 "reflect.h2" } -#line 5378 "reflect.h2" +#line 5392 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8909,7 +8922,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5388 "reflect.h2" +#line 5402 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8917,17 +8930,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5395 "reflect.h2" +#line 5409 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5399 "reflect.h2" +#line 5413 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5406 "reflect.h2" +#line 5420 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8937,7 +8950,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5415 "reflect.h2" +#line 5429 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8945,24 +8958,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5422 "reflect.h2" +#line 5436 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5430 "reflect.h2" +#line 5444 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5434 "reflect.h2" +#line 5448 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5438 "reflect.h2" +#line 5452 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8974,22 +8987,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5449 "reflect.h2" +#line 5463 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5455 "reflect.h2" +#line 5469 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5459 "reflect.h2" +#line 5473 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5463 "reflect.h2" +#line 5477 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8997,7 +9010,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5470 "reflect.h2" +#line 5484 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9009,10 +9022,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5483 "reflect.h2" +#line 5497 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5486 "reflect.h2" +#line 5500 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9052,7 +9065,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5526 "reflect.h2" +#line 5540 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9064,14 +9077,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5537 "reflect.h2" +#line 5551 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5538 "reflect.h2" +#line 5552 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5539 "reflect.h2" +#line 5553 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5541 "reflect.h2" +#line 5555 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9081,10 +9094,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5550 "reflect.h2" +#line 5564 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5552 "reflect.h2" +#line 5566 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9106,14 +9119,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5573 "reflect.h2" +#line 5587 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5574 "reflect.h2" +#line 5588 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5575 "reflect.h2" +#line 5589 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5577 "reflect.h2" +#line 5591 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9127,7 +9140,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5590 "reflect.h2" +#line 5604 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9149,7 +9162,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5611 "reflect.h2" +#line 5625 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9160,12 +9173,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5621 "reflect.h2" +#line 5635 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5622 "reflect.h2" +#line 5636 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5627 "reflect.h2" +#line 5641 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9220,7 +9233,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5681 "reflect.h2" +#line 5695 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9260,7 +9273,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5720 "reflect.h2" +#line 5734 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9276,21 +9289,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5737 "reflect.h2" +#line 5751 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5738 "reflect.h2" +#line 5752 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5739 "reflect.h2" +#line 5753 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5741 "reflect.h2" +#line 5755 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5756 "reflect.h2" +#line 5770 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9298,7 +9311,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5763 "reflect.h2" +#line 5777 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9308,22 +9321,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5781 "reflect.h2" +#line 5795 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5786 "reflect.h2" +#line 5800 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5792 "reflect.h2" +#line 5806 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5798 "reflect.h2" +#line 5812 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9332,7 +9345,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5806 "reflect.h2" +#line 5820 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9344,7 +9357,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5817 "reflect.h2" +#line 5831 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9352,7 +9365,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5824 "reflect.h2" +#line 5838 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9373,7 +9386,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5845 "reflect.h2" +#line 5859 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9383,7 +9396,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5855 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9406,33 +9419,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5879 "reflect.h2" +#line 5893 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5885 "reflect.h2" +#line 5899 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5889 "reflect.h2" +#line 5903 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5895 "reflect.h2" +#line 5909 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5903 "reflect.h2" +#line 5917 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9441,7 +9454,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5911 "reflect.h2" +#line 5925 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9450,22 +9463,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5921 "reflect.h2" +#line 5935 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5925 "reflect.h2" +#line 5939 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5929 "reflect.h2" +#line 5943 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5933 "reflect.h2" +#line 5947 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9489,18 +9502,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5958 "reflect.h2" +#line 5972 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5973 "reflect.h2" +#line 5987 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5975 "reflect.h2" +#line 5989 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9511,15 +9524,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5990 "reflect.h2" +#line 6004 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5993 "reflect.h2" +#line 6007 "reflect.h2" } -#line 5995 "reflect.h2" +#line 6009 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9537,7 +9550,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6012 "reflect.h2" +#line 6026 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9545,7 +9558,7 @@ generation_function_context::generation_function_context(){} } } -#line 6019 "reflect.h2" +#line 6033 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9559,7 +9572,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6032 "reflect.h2" +#line 6046 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9575,14 +9588,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6053 "reflect.h2" +#line 6067 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6055 "reflect.h2" +#line 6069 "reflect.h2" } -#line 6057 "reflect.h2" +#line 6071 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9591,11 +9604,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6072 "reflect.h2" +#line 6086 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6074 "reflect.h2" +#line 6088 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9603,7 +9616,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6081 "reflect.h2" +#line 6095 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9612,37 +9625,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6089 "reflect.h2" +#line 6103 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6103 "reflect.h2" +#line 6117 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6107 "reflect.h2" +#line 6121 "reflect.h2" } -#line 6109 "reflect.h2" +#line 6123 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6113 "reflect.h2" +#line 6127 "reflect.h2" } -#line 6115 "reflect.h2" +#line 6129 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6119 "reflect.h2" +#line 6133 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9651,14 +9664,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6125 "reflect.h2" +#line 6139 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6130 "reflect.h2" +#line 6144 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9671,7 +9684,7 @@ size_t i{0}; } } -#line 6142 "reflect.h2" +#line 6156 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9693,7 +9706,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6163 "reflect.h2" +#line 6177 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9712,7 +9725,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6181 "reflect.h2" +#line 6195 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9728,14 +9741,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6196 "reflect.h2" +#line 6210 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6202 "reflect.h2" +#line 6216 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9743,19 +9756,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6219 "reflect.h2" +#line 6233 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6220 "reflect.h2" +#line 6234 "reflect.h2" { -#line 6225 "reflect.h2" +#line 6239 "reflect.h2" } -#line 6228 "reflect.h2" +#line 6242 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9881,7 +9894,7 @@ size_t i{0}; ); } -#line 6353 "reflect.h2" +#line 6367 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9891,13 +9904,13 @@ size_t i{0}; ); } -#line 6362 "reflect.h2" +#line 6376 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6367 "reflect.h2" +#line 6381 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9908,12 +9921,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6379 "reflect.h2" +#line 6393 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6384 "reflect.h2" +#line 6398 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9947,7 +9960,7 @@ size_t i{0}; } -#line 6420 "reflect.h2" +#line 6434 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9956,19 +9969,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6443 "reflect.h2" +#line 6457 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6444 "reflect.h2" +#line 6458 "reflect.h2" { -#line 6449 "reflect.h2" +#line 6463 "reflect.h2" } -#line 6451 "reflect.h2" +#line 6465 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10070,19 +10083,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6552 "reflect.h2" +#line 6566 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6556 "reflect.h2" +#line 6570 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6580 "reflect.h2" +#line 6594 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10101,7 +10114,7 @@ size_t i{0}; return r; } -#line 6598 "reflect.h2" +#line 6612 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10116,7 +10129,7 @@ size_t i{0}; return r; } -#line 6612 "reflect.h2" +#line 6626 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10276,7 +10289,7 @@ size_t i{0}; } } -#line 6771 "reflect.h2" +#line 6785 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10285,7 +10298,7 @@ size_t i{0}; return r; } -#line 6779 "reflect.h2" +#line 6793 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10304,7 +10317,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6797 "reflect.h2" +#line 6811 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10336,7 +10349,7 @@ size_t i{0}; } } -#line 6828 "reflect.h2" +#line 6842 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10347,7 +10360,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6840 "reflect.h2" +#line 6854 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10386,7 +10399,7 @@ size_t i{0}; return r; } -#line 6881 "reflect.h2" +#line 6895 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10404,7 +10417,7 @@ size_t i{0}; }} } -#line 6901 "reflect.h2" +#line 6915 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10418,16 +10431,16 @@ size_t i{0}; } } -#line 6927 "reflect.h2" +#line 6941 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6930 "reflect.h2" +#line 6944 "reflect.h2" } -#line 6932 "reflect.h2" +#line 6946 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10439,7 +10452,7 @@ size_t i{0}; } } -#line 6943 "reflect.h2" +#line 6957 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10447,14 +10460,14 @@ size_t i{0}; return r; } -#line 6950 "reflect.h2" +#line 6964 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6958 "reflect.h2" +#line 6972 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10480,7 +10493,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6986 "reflect.h2" +#line 7000 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10506,11 +10519,11 @@ size_t i{0}; return r; } -#line 7023 "reflect.h2" +#line 7037 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7025 "reflect.h2" +#line 7039 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10584,7 +10597,7 @@ size_t i{0}; return nullptr; } -#line 7098 "reflect.h2" +#line 7112 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10597,7 +10610,7 @@ size_t i{0}; }} } -#line 7110 "reflect.h2" +#line 7124 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10611,7 +10624,7 @@ size_t i{0}; }} } -#line 7123 "reflect.h2" +#line 7137 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10631,7 +10644,7 @@ size_t i{0}; return r; } -#line 7142 "reflect.h2" +#line 7156 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10642,7 +10655,7 @@ size_t i{0}; return r; } -#line 7152 "reflect.h2" +#line 7166 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10654,14 +10667,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7163 "reflect.h2" +#line 7177 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7175 "reflect.h2" +#line 7189 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10685,7 +10698,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7199 "reflect.h2" +#line 7213 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10695,7 +10708,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7211 "reflect.h2" +#line 7225 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10711,7 +10724,7 @@ size_t i{0}; } } -#line 7231 "reflect.h2" +#line 7245 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10729,15 +10742,15 @@ size_t i{0}; }} } -#line 7267 "reflect.h2" +#line 7281 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7270 "reflect.h2" +#line 7284 "reflect.h2" } -#line 7272 "reflect.h2" +#line 7286 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10773,7 +10786,7 @@ size_t i{0}; return source; } -#line 7307 "reflect.h2" +#line 7321 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10789,7 +10802,7 @@ size_t i{0}; } } -#line 7323 "reflect.h2" +#line 7337 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10798,7 +10811,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10853,7 +10866,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7392 "reflect.h2" +#line 7406 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10975,7 +10988,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7514 "reflect.h2" +#line 7528 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index bd1ac1417..1004bdf6a 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4000,11 +4000,15 @@ autodiff_expression_handler: type = { public declare_p: std::string; public declare_d: std::string; - operator=: (out this, ctx_: *autodiff_context, lhs_: std::string, declare_: std::string = "") = { + operator=: (out this, ctx_: *autodiff_context, lhs_: std::string, declare_p_: std::string = "", declare_d_: std::string = "") = { autodiff_handler_base = (ctx_); lhs = lhs_; - declare_p = declare_; - declare_d = declare_; + declare_p = declare_p_; + declare_d = declare_d_; + + if declare_d.empty() && !declare_p.empty() { + declare_d = declare_p; + } } gen_lhs_assignment: (inout this, prim: std::string, fwd: std::string, primal_first: bool = false) = { @@ -4373,10 +4377,15 @@ autodiff_expression_handler: type = { gen_lhs_assignment(primary.to_string(), primary.to_string() + "_d"); } else if primary.is_expression_list() { - primary.error("AD: Do not know how to handle expression list inside of primary_expression: (primary.to_string())$"); + if primary.as_expression_list().is_empty() { + gen_lhs_assignment("()", "()"); + } + else { + primary.error("AD: Do not know how to handle non empty expression list inside of primary_expression: (primary.to_string())$"); + } } else if primary.is_literal() { - gen_lhs_assignment(primary.to_string(), "()"); + gen_lhs_assignment(primary.to_string(), "0.0"); } else if primary.is_declaration() { primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); @@ -4411,15 +4420,20 @@ autodiff_stmt_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { - lhs := o.name(); - type := o.type(); + lhs : std::string = o.name(); + type : = o.type(); - ad_type := ctx*.get_ad_type(type); + ad_type : = ctx*.get_ad_type(type); - // TODO: Get initializer as expression and handle it. - init := o.initializer(); - diff += "(lhs)$_d : (ad_type)$ = (init)$;\n"; - diff += "(lhs)$ : (ad_type)$ = (init)$;\n"; + if o.has_initializer() { + ad: autodiff_expression_handler = (ctx, lhs, ": " + type, ": " + ad_type); + ad.pre_traverse(o.get_initializer()); + append(ad); + } + else { + diff += "(lhs)$_d : (ad_type)$;\n"; + diff += "(lhs)$ : (type)$;\n"; + } } From 8548b9bf8a3b3f47136b1d60188bf31736112ae3 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 13:50:12 +0200 Subject: [PATCH 18/54] Fix initializer problem. --- .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 + .../test-results/pure2-autodiff.cpp | 10 +- .../test-results/pure2-autodiff.cpp2.output | 10 +- source/reflect.h | 1103 ++++++++--------- source/reflect.h2 | 45 +- 5 files changed, 583 insertions(+), 587 deletions(-) diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 77f4ca3a7..387d130b1 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -18,6 +18,8 @@ diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.0000 diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate default init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 492fd52f4..393feaf08 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -675,7 +675,7 @@ int i_d {}; int i {}; r_d = x_d + y_d; r = x + y; - i_d = 0.0; + i_d = { }; i = 2; static_cast(cpp2::move(i_d)); static_cast(cpp2::move(i)); @@ -710,7 +710,7 @@ double t_d {}; [[nodiscard]] auto ad_test::intermediate_no_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_diff_ret{ double r {0.0}; - double r_d {0.0};r_d = 0.0; + double r_d {0.0};r_d = { }; r = 0.0; cpp2::impl::deferred_init t_d; @@ -726,7 +726,7 @@ double t_d {}; [[nodiscard]] auto ad_test::while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret{ double r {0.0}; double r_d {0.0}; -int i_d {0.0}; +int i_d {}; int i {0}; r_d = x_d; @@ -741,7 +741,7 @@ int i_d {0.0}; [[nodiscard]] auto ad_test::do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret{ double r {0.0}; double r_d {0.0}; -int i_d {0.0}; +int i_d {}; int i {0}; r_d = x_d; @@ -768,7 +768,7 @@ std::vector v_d {}; CPP2_UFCS(push_back)(v_d, x_d); CPP2_UFCS(push_back)(v, y); CPP2_UFCS(push_back)(v_d, y_d); - r_d = 0.0; + r_d = { }; r = 0.0; { auto t_d_iter{CPP2_UFCS(begin)(cpp2::move(v_d))}; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 06311e58b..7e730409e 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -610,7 +610,7 @@ ad_test:/* @autodiff @print */ type = i: int = (); r_d = x_d + y_d; r = x + y; - i_d = 0.0; + i_d = (); i = 2; _ = i_d; _ = i; @@ -665,7 +665,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - r_d = 0.0; + r_d = (); r = 0.0; t_d: double; t: double; @@ -686,7 +686,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = 0.0; + i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -709,7 +709,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = 0.0; + i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -739,7 +739,7 @@ ad_test:/* @autodiff @print */ type = v_d.push_back(x_d); v.push_back(y); v_d.push_back(y_d); - r_d = 0.0; + r_d = (); r = 0.0; (copy t_d_iter: _ = v_d.begin(), ) for v diff --git a/source/reflect.h b/source/reflect.h index 19e7b67f1..01c963548 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -109,88 +109,88 @@ class autodiff_special_func; class autodiff_context; -#line 3979 "reflect.h2" +#line 3987 "reflect.h2" class autodiff_handler_base; -#line 3993 "reflect.h2" +#line 4001 "reflect.h2" class autodiff_expression_handler; -#line 4399 "reflect.h2" +#line 4394 "reflect.h2" class autodiff_stmt_handler; -#line 5106 "reflect.h2" +#line 5101 "reflect.h2" class expression_flags; -#line 5122 "reflect.h2" +#line 5117 "reflect.h2" class regex_token; -#line 5149 "reflect.h2" +#line 5144 "reflect.h2" class regex_token_check; -#line 5170 "reflect.h2" +#line 5165 "reflect.h2" class regex_token_code; -#line 5191 "reflect.h2" +#line 5186 "reflect.h2" class regex_token_empty; -#line 5209 "reflect.h2" +#line 5204 "reflect.h2" class regex_token_list; -#line 5261 "reflect.h2" +#line 5256 "reflect.h2" class parse_context_group_state; -#line 5322 "reflect.h2" +#line 5317 "reflect.h2" class parse_context_branch_reset_state; -#line 5365 "reflect.h2" +#line 5360 "reflect.h2" class parse_context; -#line 5766 "reflect.h2" +#line 5761 "reflect.h2" class generation_function_context; -#line 5784 "reflect.h2" +#line 5779 "reflect.h2" class generation_context; -#line 5983 "reflect.h2" +#line 5978 "reflect.h2" class alternative_token; -#line 5998 "reflect.h2" +#line 5993 "reflect.h2" class alternative_token_gen; -#line 6063 "reflect.h2" +#line 6058 "reflect.h2" class any_token; -#line 6080 "reflect.h2" +#line 6075 "reflect.h2" class atomic_group_token; -#line 6110 "reflect.h2" +#line 6105 "reflect.h2" class char_token; -#line 6225 "reflect.h2" +#line 6220 "reflect.h2" class class_token; -#line 6449 "reflect.h2" +#line 6444 "reflect.h2" class group_ref_token; -#line 6586 "reflect.h2" +#line 6581 "reflect.h2" class group_token; -#line 6933 "reflect.h2" +#line 6928 "reflect.h2" class lookahead_lookbehind_token; -#line 7028 "reflect.h2" +#line 7023 "reflect.h2" class range_token; -#line 7185 "reflect.h2" +#line 7180 "reflect.h2" class special_range_token; -#line 7271 "reflect.h2" +#line 7266 "reflect.h2" template class regex_generator; -#line 7528 "reflect.h2" +#line 7523 "reflect.h2" } } @@ -1621,34 +1621,42 @@ class autodiff_special_func { class autodiff_context { private: int temporary_count {0}; - public: std::map math_funcs { - std::make_pair("sin", "cos(_x_)"), - std::make_pair("cos", "-sin(_x_)"), - std::make_pair("exp", "exp(_x_)")}; -#line 3945 "reflect.h2" +#line 3941 "reflect.h2" public: std::vector special_funcs { + autodiff_special_func("sin", 1, true, false, + "_rd_ = cos(_a1_) * _ad1_;\n" + "_r_ = sin(_a1_);\n" + ), + autodiff_special_func("cos", 1, true, false, + "_rd_ = -sin(_a1_) * _ad1_;\n" + "_r_ = cos(_a1_);\n" + ), + autodiff_special_func("exp", 1, true, false, + "_rd_ = exp(_a1_) * _ad1_;\n" + "_r_ = exp(_a1_);\n" + ), autodiff_special_func("push_back", 1, false, true, "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n")}; -#line 3951 "reflect.h2" +#line 3959 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 3957 "reflect.h2" +#line 3965 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 3964 "reflect.h2" +#line 3972 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3977 "reflect.h2" +#line 3985 "reflect.h2" }; class autodiff_handler_base { @@ -1657,21 +1665,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3984 "reflect.h2" +#line 3992 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3988 "reflect.h2" +#line 3996 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3991 "reflect.h2" +#line 3999 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 3997 "reflect.h2" +#line 4005 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1680,183 +1688,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4014 "reflect.h2" +#line 4022 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4033 "reflect.h2" +#line 4041 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4042 "reflect.h2" +#line 4050 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4080 "reflect.h2" +#line 4088 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4181 "reflect.h2" - public: [[nodiscard]] auto handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool; - -#line 4195 "reflect.h2" +#line 4185 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4228 "reflect.h2" +#line 4218 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4232 "reflect.h2" +#line 4222 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4236 "reflect.h2" +#line 4226 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4240 "reflect.h2" +#line 4230 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4244 "reflect.h2" +#line 4234 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4248 "reflect.h2" +#line 4238 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4252 "reflect.h2" +#line 4242 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4256 "reflect.h2" +#line 4246 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4260 "reflect.h2" +#line 4250 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4264 "reflect.h2" +#line 4254 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4268 "reflect.h2" +#line 4258 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4272 "reflect.h2" +#line 4262 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4295 "reflect.h2" +#line 4285 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4338 "reflect.h2" +#line 4328 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4342 "reflect.h2" +#line 4332 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4347 "reflect.h2" +#line 4337 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4374 "reflect.h2" +#line 4364 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4397 "reflect.h2" +#line 4392 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4403 "reflect.h2" +#line 4398 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4412 "reflect.h2" +#line 4407 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4417 "reflect.h2" +#line 4412 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4422 "reflect.h2" +#line 4417 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4440 "reflect.h2" +#line 4435 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4445 "reflect.h2" +#line 4440 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4450 "reflect.h2" +#line 4445 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4455 "reflect.h2" +#line 4450 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4463 "reflect.h2" +#line 4458 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4479 "reflect.h2" +#line 4474 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4526 "reflect.h2" +#line 4521 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4537 "reflect.h2" +#line 4532 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4565 "reflect.h2" +#line 4560 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4570 "reflect.h2" +#line 4565 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4574 "reflect.h2" +#line 4569 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4578 "reflect.h2" +#line 4573 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4582 "reflect.h2" +#line 4577 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4586 "reflect.h2" +#line 4581 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4590 "reflect.h2" +#line 4585 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4594 "reflect.h2" +#line 4589 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4598 "reflect.h2" +#line 4593 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4602 "reflect.h2" +#line 4597 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4606 "reflect.h2" +#line 4601 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4610 "reflect.h2" +#line 4605 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4614 "reflect.h2" +#line 4609 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4618 "reflect.h2" +#line 4613 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4623 "reflect.h2" +#line 4618 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4652 "reflect.h2" +#line 4647 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4656 "reflect.h2" +#line 4651 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 5102 "reflect.h2" +#line 5097 "reflect.h2" using error_func = std::function x)>; -#line 5106 "reflect.h2" +#line 5101 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1891,20 +1896,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5114 "reflect.h2" +#line 5109 "reflect.h2" }; -#line 5122 "reflect.h2" +#line 5117 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5130 "reflect.h2" +#line 5125 "reflect.h2" public: explicit regex_token(); -#line 5135 "reflect.h2" +#line 5130 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1916,103 +1921,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5141 "reflect.h2" +#line 5136 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5147 "reflect.h2" +#line 5142 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5153 "reflect.h2" +#line 5148 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5160 "reflect.h2" +#line 5155 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5164 "reflect.h2" +#line 5159 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5165 "reflect.h2" +#line 5160 "reflect.h2" }; -#line 5168 "reflect.h2" +#line 5163 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5174 "reflect.h2" +#line 5169 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5181 "reflect.h2" +#line 5176 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5185 "reflect.h2" +#line 5180 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5186 "reflect.h2" +#line 5181 "reflect.h2" }; -#line 5189 "reflect.h2" +#line 5184 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5195 "reflect.h2" +#line 5190 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5199 "reflect.h2" +#line 5194 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5203 "reflect.h2" +#line 5198 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5204 "reflect.h2" +#line 5199 "reflect.h2" }; -#line 5207 "reflect.h2" +#line 5202 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5213 "reflect.h2" +#line 5208 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5220 "reflect.h2" +#line 5215 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5226 "reflect.h2" +#line 5221 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5232 "reflect.h2" +#line 5227 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5240 "reflect.h2" +#line 5235 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2020,10 +2025,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5252 "reflect.h2" +#line 5247 "reflect.h2" }; -#line 5255 "reflect.h2" +#line 5250 "reflect.h2" // // Parse and generation context. // @@ -2039,33 +2044,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5275 "reflect.h2" +#line 5270 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5282 "reflect.h2" +#line 5277 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5294 "reflect.h2" +#line 5289 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5299 "reflect.h2" +#line 5294 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5303 "reflect.h2" +#line 5298 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5317 "reflect.h2" +#line 5312 "reflect.h2" }; -#line 5320 "reflect.h2" +#line 5315 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2078,25 +2083,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5338 "reflect.h2" +#line 5333 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5344 "reflect.h2" +#line 5339 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5351 "reflect.h2" +#line 5346 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5358 "reflect.h2" +#line 5353 "reflect.h2" }; -#line 5361 "reflect.h2" +#line 5356 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2112,7 +2117,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5377 "reflect.h2" +#line 5372 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2120,64 +2125,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5388 "reflect.h2" +#line 5383 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5401 "reflect.h2" +#line 5396 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5409 "reflect.h2" +#line 5404 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5413 "reflect.h2" +#line 5408 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5417 "reflect.h2" +#line 5412 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5429 "reflect.h2" +#line 5424 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5436 "reflect.h2" +#line 5431 "reflect.h2" public: auto next_alternative() & -> void; -#line 5442 "reflect.h2" +#line 5437 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5448 "reflect.h2" +#line 5443 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5452 "reflect.h2" +#line 5447 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5463 "reflect.h2" +#line 5458 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5467 "reflect.h2" +#line 5462 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5473 "reflect.h2" +#line 5468 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5477 "reflect.h2" +#line 5472 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5484 "reflect.h2" +#line 5479 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5495 "reflect.h2" +#line 5490 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2185,51 +2190,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5539 "reflect.h2" +#line 5534 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5551 "reflect.h2" +#line 5546 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5564 "reflect.h2" +#line 5559 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5587 "reflect.h2" +#line 5582 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5604 "reflect.h2" +#line 5599 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5625 "reflect.h2" +#line 5620 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5635 "reflect.h2" +#line 5630 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5639 "reflect.h2" +#line 5634 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5695 "reflect.h2" +#line 5690 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5734 "reflect.h2" +#line 5729 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5749 "reflect.h2" +#line 5744 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2241,10 +2246,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5760 "reflect.h2" +#line 5755 "reflect.h2" }; -#line 5763 "reflect.h2" +#line 5758 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2254,16 +2259,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5777 "reflect.h2" +#line 5772 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5780 "reflect.h2" +#line 5775 "reflect.h2" }; -#line 5783 "reflect.h2" +#line 5778 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2283,68 +2288,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5805 "reflect.h2" +#line 5800 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5811 "reflect.h2" +#line 5806 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5820 "reflect.h2" +#line 5815 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5831 "reflect.h2" +#line 5826 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5838 "reflect.h2" +#line 5833 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5858 "reflect.h2" +#line 5853 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5868 "reflect.h2" +#line 5863 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5891 "reflect.h2" +#line 5886 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5899 "reflect.h2" +#line 5894 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5903 "reflect.h2" +#line 5898 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5909 "reflect.h2" +#line 5904 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5915 "reflect.h2" +#line 5910 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5925 "reflect.h2" +#line 5920 "reflect.h2" public: auto finish_context() & -> void; -#line 5933 "reflect.h2" +#line 5928 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5939 "reflect.h2" +#line 5934 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5943 "reflect.h2" +#line 5938 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5947 "reflect.h2" +#line 5942 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5971 "reflect.h2" +#line 5966 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2352,7 +2357,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5977 "reflect.h2" +#line 5972 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2372,27 +2377,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5996 "reflect.h2" +#line 5991 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6002 "reflect.h2" +#line 5997 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6009 "reflect.h2" +#line 6004 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6026 "reflect.h2" +#line 6021 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6033 "reflect.h2" +#line 6028 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6046 "reflect.h2" +#line 6041 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2400,19 +2405,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6058 "reflect.h2" +#line 6053 "reflect.h2" }; -#line 6061 "reflect.h2" +#line 6056 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6067 "reflect.h2" +#line 6062 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6071 "reflect.h2" +#line 6066 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2420,7 +2425,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6076 "reflect.h2" +#line 6071 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2428,17 +2433,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6084 "reflect.h2" +#line 6079 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6095 "reflect.h2" +#line 6090 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6103 "reflect.h2" +#line 6098 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2446,7 +2451,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6106 "reflect.h2" +#line 6101 "reflect.h2" }; // Regex syntax: a @@ -2454,34 +2459,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6114 "reflect.h2" +#line 6109 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6123 "reflect.h2" +#line 6118 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6129 "reflect.h2" +#line 6124 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6133 "reflect.h2" +#line 6128 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6156 "reflect.h2" +#line 6151 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6177 "reflect.h2" +#line 6172 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6195 "reflect.h2" +#line 6190 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6210 "reflect.h2" +#line 6205 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6216 "reflect.h2" +#line 6211 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2489,33 +2494,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6220 "reflect.h2" +#line 6215 "reflect.h2" }; -#line 6223 "reflect.h2" +#line 6218 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6229 "reflect.h2" +#line 6224 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6241 "reflect.h2" +#line 6236 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6367 "reflect.h2" +#line 6362 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6376 "reflect.h2" +#line 6371 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6381 "reflect.h2" +#line 6376 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2523,20 +2528,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6388 "reflect.h2" +#line 6383 "reflect.h2" }; -#line 6391 "reflect.h2" +#line 6386 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6432 "reflect.h2" +#line 6427 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6443 "reflect.h2" +#line 6438 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2546,20 +2551,20 @@ class class_token class group_ref_token : public regex_token { -#line 6453 "reflect.h2" +#line 6448 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6465 "reflect.h2" +#line 6460 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6566 "reflect.h2" +#line 6561 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6570 "reflect.h2" +#line 6565 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2567,10 +2572,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6573 "reflect.h2" +#line 6568 "reflect.h2" }; -#line 6576 "reflect.h2" +#line 6571 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2584,29 +2589,29 @@ class group_ref_token class group_token : public regex_token { -#line 6590 "reflect.h2" +#line 6585 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6612 "reflect.h2" +#line 6607 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6626 "reflect.h2" +#line 6621 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6785 "reflect.h2" +#line 6780 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6793 "reflect.h2" +#line 6788 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6811 "reflect.h2" +#line 6806 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6842 "reflect.h2" +#line 6837 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2615,25 +2620,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6849 "reflect.h2" +#line 6844 "reflect.h2" }; -#line 6852 "reflect.h2" +#line 6847 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6893 "reflect.h2" +#line 6888 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6913 "reflect.h2" +#line 6908 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6929 "reflect.h2" +#line 6924 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2641,20 +2646,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6937 "reflect.h2" +#line 6932 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6946 "reflect.h2" +#line 6941 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6957 "reflect.h2" +#line 6952 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6964 "reflect.h2" +#line 6959 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2662,26 +2667,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6967 "reflect.h2" +#line 6962 "reflect.h2" }; -#line 6970 "reflect.h2" +#line 6965 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6998 "reflect.h2" +#line 6993 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7026 "reflect.h2" +#line 7021 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7032 "reflect.h2" +#line 7027 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2691,22 +2696,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7112 "reflect.h2" +#line 7107 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7124 "reflect.h2" +#line 7119 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7137 "reflect.h2" +#line 7132 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7156 "reflect.h2" +#line 7151 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7166 "reflect.h2" +#line 7161 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7177 "reflect.h2" +#line 7172 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2714,16 +2719,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7180 "reflect.h2" +#line 7175 "reflect.h2" }; -#line 7183 "reflect.h2" +#line 7178 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7189 "reflect.h2" +#line 7184 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2732,7 +2737,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7219 "reflect.h2" +#line 7214 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2741,14 +2746,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7241 "reflect.h2" +#line 7236 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7263 "reflect.h2" +#line 7258 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2769,24 +2774,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7286 "reflect.h2" +#line 7281 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7321 "reflect.h2" +#line 7316 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7335 "reflect.h2" +#line 7330 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7347 "reflect.h2" +#line 7342 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7402 "reflect.h2" +#line 7397 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2797,7 +2802,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7528 "reflect.h2" +#line 7523 "reflect.h2" } } @@ -7347,28 +7352,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; } -#line 3935 "reflect.h2" - // TODO: Extend - -#line 3938 "reflect.h2" +#line 3932 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. + // _r_ : name of the return value. + // _rd_ : name of derivative return value. // _a1_ : First argument value // _ad1_: First derivative argument value // _a2_ : Second argument value // _ad2_: Second derivative argument value + /* has_return = */ /* is_member = */ + +#line 3946 "reflect.h2" + /* has_return = */ /* is_member = */ + +#line 3950 "reflect.h2" + /* has_return = */ /* is_member = */ + +#line 3954 "reflect.h2" /* has_return = */ /* is_member = */ -#line 3951 "reflect.h2" +#line 3959 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 3957 "reflect.h2" +#line 3965 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ // TODO: Add type to required generation for AD. @@ -7376,11 +7389,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return type; // Use the same type for now. } -#line 3964 "reflect.h2" +#line 3972 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 3965 "reflect.h2" +#line 3973 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7394,27 +7407,27 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return { std::move(m.value()), std::move(code.value()) }; } -#line 3984 "reflect.h2" +#line 3992 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3986 "reflect.h2" +#line 3994 "reflect.h2" } -#line 3984 "reflect.h2" +#line 3992 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3986 "reflect.h2" +#line 3994 "reflect.h2" } -#line 3988 "reflect.h2" +#line 3996 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4003 "reflect.h2" +#line 4011 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7422,13 +7435,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4009 "reflect.h2" +#line 4017 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4014 "reflect.h2" +#line 4022 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + "_d"}; if (lhs == "_") { @@ -7448,7 +7461,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4033 "reflect.h2" +#line 4041 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7458,7 +7471,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4042 "reflect.h2" +#line 4050 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7497,7 +7510,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4080 "reflect.h2" +#line 4088 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7505,7 +7518,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4086 "reflect.h2" +#line 4094 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7519,7 +7532,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4098 "reflect.h2" +#line 4106 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7542,7 +7555,7 @@ auto i{0}; { auto i{0}; -#line 4119 "reflect.h2" +#line 4127 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7567,7 +7580,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7575,10 +7588,6 @@ auto i{0}; if (handle_special_function(object, cpp2::move(object_d), function_name, args, cpp2::move(r_arg))) { return ; } - // TODO: Extend to a generalized version and not only functions with one argument. - if (handle_math_func(function_name, CPP2_ASSERT_IN_BOUNDS_LITERAL(args, 0))) { - return ; - } // No special handling, currently only allow direct function calls if (!(CPP2_UFCS(empty)(cpp2::move(object)))) { @@ -7607,22 +7616,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation. } -#line 4181 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_math_func(cpp2::impl::in func_name, cpp2::impl::in arg) & -> bool{ - auto pos {CPP2_UFCS(find)((*cpp2::impl::assert_not_null(ctx)).math_funcs, func_name)}; - - if (pos == CPP2_UFCS(end)((*cpp2::impl::assert_not_null(ctx)).math_funcs)) { - return false; - } - - auto func_diff {string_util::replace_all((*cpp2::impl::assert_not_null(cpp2::move(pos))).second, "_x_", arg)}; - - gen_lhs_assignment("" + cpp2::to_string(func_name) + "(" + cpp2::to_string(arg) + ")", "" + cpp2::to_string(cpp2::move(func_diff)) + " * " + cpp2::to_string(arg) + "_d"); - - return true; - } - -#line 4195 "reflect.h2" +#line 4185 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7647,75 +7641,75 @@ auto i{0}; { auto i{1}; -#line 4218 "reflect.h2" +#line 4208 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); } } -#line 4223 "reflect.h2" +#line 4213 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4228 "reflect.h2" +#line 4218 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4232 "reflect.h2" +#line 4222 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4236 "reflect.h2" +#line 4226 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4240 "reflect.h2" +#line 4230 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4244 "reflect.h2" +#line 4234 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4248 "reflect.h2" +#line 4238 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4252 "reflect.h2" +#line 4242 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4256 "reflect.h2" +#line 4246 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4260 "reflect.h2" +#line 4250 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4264 "reflect.h2" +#line 4254 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4268 "reflect.h2" +#line 4258 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4272 "reflect.h2" +#line 4262 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7739,7 +7733,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4295 "reflect.h2" +#line 4285 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7766,7 +7760,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4322 "reflect.h2" +#line 4312 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7783,18 +7777,18 @@ auto i{1}; } } -#line 4338 "reflect.h2" +#line 4328 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4342 "reflect.h2" +#line 4332 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4347 "reflect.h2" +#line 4337 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7803,7 +7797,7 @@ auto i{1}; { auto i{0}; -#line 4354 "reflect.h2" +#line 4344 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7817,7 +7811,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4366 "reflect.h2" +#line 4356 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7826,7 +7820,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4374 "reflect.h2" +#line 4364 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7841,7 +7835,12 @@ auto i{0}; } } else {if (CPP2_UFCS(is_literal)(primary)) { - gen_lhs_assignment(CPP2_UFCS(to_string)(primary), "0.0"); + // TODO: Determine propre zero initializer from type of literal. + std::string ad_init {"()"}; + if (declare_d == ":" || declare_d == ": _") { + ad_init = "0.0"; + } + gen_lhs_assignment(CPP2_UFCS(to_string)(primary), cpp2::move(ad_init)); } else {if (CPP2_UFCS(is_declaration)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -7851,26 +7850,26 @@ auto i{0}; }}}} } -#line 4407 "reflect.h2" +#line 4402 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4410 "reflect.h2" +#line 4405 "reflect.h2" } -#line 4412 "reflect.h2" +#line 4407 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4417 "reflect.h2" +#line 4412 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4422 "reflect.h2" +#line 4417 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7888,22 +7887,22 @@ auto i{0}; } } -#line 4440 "reflect.h2" +#line 4435 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4445 "reflect.h2" +#line 4440 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4450 "reflect.h2" +#line 4445 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4455 "reflect.h2" +#line 4450 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7911,7 +7910,7 @@ auto i{0}; diff += "}\n"; } -#line 4463 "reflect.h2" +#line 4458 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7927,7 +7926,7 @@ auto i{0}; } } -#line 4479 "reflect.h2" +#line 4474 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -7974,7 +7973,7 @@ auto i{0}; }} } -#line 4526 "reflect.h2" +#line 4521 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7986,7 +7985,7 @@ auto i{0}; } } -#line 4537 "reflect.h2" +#line 4532 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8015,79 +8014,79 @@ auto i{0}; } } -#line 4565 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4570 "reflect.h2" +#line 4565 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4574 "reflect.h2" +#line 4569 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4578 "reflect.h2" +#line 4573 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4582 "reflect.h2" +#line 4577 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4586 "reflect.h2" +#line 4581 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4590 "reflect.h2" +#line 4585 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4594 "reflect.h2" +#line 4589 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4598 "reflect.h2" +#line 4593 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4602 "reflect.h2" +#line 4597 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4606 "reflect.h2" +#line 4601 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4610 "reflect.h2" +#line 4605 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4614 "reflect.h2" +#line 4609 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4618 "reflect.h2" +#line 4613 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4623 "reflect.h2" +#line 4618 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8096,7 +8095,7 @@ auto i{0}; { auto i{0}; -#line 4630 "reflect.h2" +#line 4625 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8110,7 +8109,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4642 "reflect.h2" +#line 4637 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8121,13 +8120,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4652 "reflect.h2" +#line 4647 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4658 "reflect.h2" +#line 4653 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { for ( @@ -8179,7 +8178,7 @@ auto autodiff(meta::type_declaration& t) -> void autodiff_context ad_ctx {}; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4710 "reflect.h2" +#line 4705 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8283,7 +8282,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4723 "reflect.h2" +#line 4718 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8648,7 +8647,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 5088 "reflect.h2" +#line 5083 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8664,11 +8663,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5104 "reflect.h2" +#line 5099 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5108 "reflect.h2" +#line 5103 "reflect.h2" // mod: i // mod: m // mod: s @@ -8676,116 +8675,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5117 "reflect.h2" +#line 5112 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5126 "reflect.h2" +#line 5121 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5128 "reflect.h2" +#line 5123 "reflect.h2" } -#line 5130 "reflect.h2" +#line 5125 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5132 "reflect.h2" +#line 5127 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5138 "reflect.h2" +#line 5133 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5139 "reflect.h2" +#line 5134 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5140 "reflect.h2" +#line 5135 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5155 "reflect.h2" +#line 5150 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5158 "reflect.h2" +#line 5153 "reflect.h2" } -#line 5160 "reflect.h2" +#line 5155 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5164 "reflect.h2" +#line 5159 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5176 "reflect.h2" +#line 5171 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5179 "reflect.h2" +#line 5174 "reflect.h2" } -#line 5181 "reflect.h2" +#line 5176 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5185 "reflect.h2" +#line 5180 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5195 "reflect.h2" +#line 5190 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5197 "reflect.h2" +#line 5192 "reflect.h2" } -#line 5199 "reflect.h2" +#line 5194 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5203 "reflect.h2" +#line 5198 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5215 "reflect.h2" +#line 5210 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5218 "reflect.h2" +#line 5213 "reflect.h2" } -#line 5220 "reflect.h2" +#line 5215 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5226 "reflect.h2" +#line 5221 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5232 "reflect.h2" +#line 5227 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8794,7 +8793,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5240 "reflect.h2" +#line 5235 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8810,7 +8809,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5268 "reflect.h2" +#line 5263 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8818,14 +8817,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5276 "reflect.h2" +#line 5271 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5283 "reflect.h2" +#line 5278 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8837,15 +8836,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5295 "reflect.h2" +#line 5290 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5300 "reflect.h2" +#line 5295 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5304 "reflect.h2" +#line 5299 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8866,7 +8865,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5330 "reflect.h2" +#line 5325 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8875,20 +8874,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5339 "reflect.h2" +#line 5334 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5345 "reflect.h2" +#line 5340 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5352 "reflect.h2" +#line 5347 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8903,16 +8902,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5382 "reflect.h2" +#line 5377 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5386 "reflect.h2" +#line 5381 "reflect.h2" } -#line 5392 "reflect.h2" +#line 5387 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8922,7 +8921,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5402 "reflect.h2" +#line 5397 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8930,17 +8929,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5409 "reflect.h2" +#line 5404 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5413 "reflect.h2" +#line 5408 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5420 "reflect.h2" +#line 5415 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8950,7 +8949,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5429 "reflect.h2" +#line 5424 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8958,24 +8957,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5436 "reflect.h2" +#line 5431 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5444 "reflect.h2" +#line 5439 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5448 "reflect.h2" +#line 5443 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5452 "reflect.h2" +#line 5447 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8987,22 +8986,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5463 "reflect.h2" +#line 5458 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5469 "reflect.h2" +#line 5464 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5473 "reflect.h2" +#line 5468 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5477 "reflect.h2" +#line 5472 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9010,7 +9009,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5484 "reflect.h2" +#line 5479 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9022,10 +9021,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5497 "reflect.h2" +#line 5492 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5500 "reflect.h2" +#line 5495 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9065,7 +9064,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5540 "reflect.h2" +#line 5535 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9077,14 +9076,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5551 "reflect.h2" +#line 5546 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5552 "reflect.h2" +#line 5547 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5553 "reflect.h2" +#line 5548 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5555 "reflect.h2" +#line 5550 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9094,10 +9093,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5564 "reflect.h2" +#line 5559 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5566 "reflect.h2" +#line 5561 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9119,14 +9118,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5587 "reflect.h2" +#line 5582 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5588 "reflect.h2" +#line 5583 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5589 "reflect.h2" +#line 5584 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5591 "reflect.h2" +#line 5586 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9140,7 +9139,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5604 "reflect.h2" +#line 5599 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9162,7 +9161,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5625 "reflect.h2" +#line 5620 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9173,12 +9172,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5635 "reflect.h2" +#line 5630 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5636 "reflect.h2" +#line 5631 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5641 "reflect.h2" +#line 5636 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9233,7 +9232,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5695 "reflect.h2" +#line 5690 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9273,7 +9272,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5734 "reflect.h2" +#line 5729 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9289,21 +9288,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5751 "reflect.h2" +#line 5746 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5752 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5753 "reflect.h2" +#line 5748 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5755 "reflect.h2" +#line 5750 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5770 "reflect.h2" +#line 5765 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9311,7 +9310,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5777 "reflect.h2" +#line 5772 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9321,22 +9320,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5795 "reflect.h2" +#line 5790 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5800 "reflect.h2" +#line 5795 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5806 "reflect.h2" +#line 5801 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5812 "reflect.h2" +#line 5807 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9345,7 +9344,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5820 "reflect.h2" +#line 5815 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9357,7 +9356,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5831 "reflect.h2" +#line 5826 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9365,7 +9364,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5838 "reflect.h2" +#line 5833 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9386,7 +9385,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5859 "reflect.h2" +#line 5854 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9396,7 +9395,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5869 "reflect.h2" +#line 5864 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9419,33 +9418,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5893 "reflect.h2" +#line 5888 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5899 "reflect.h2" +#line 5894 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5903 "reflect.h2" +#line 5898 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5909 "reflect.h2" +#line 5904 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5917 "reflect.h2" +#line 5912 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9454,7 +9453,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5925 "reflect.h2" +#line 5920 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9463,22 +9462,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5935 "reflect.h2" +#line 5930 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5939 "reflect.h2" +#line 5934 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5943 "reflect.h2" +#line 5938 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5947 "reflect.h2" +#line 5942 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9502,18 +9501,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5972 "reflect.h2" +#line 5967 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5987 "reflect.h2" +#line 5982 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5989 "reflect.h2" +#line 5984 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9524,15 +9523,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6004 "reflect.h2" +#line 5999 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6007 "reflect.h2" +#line 6002 "reflect.h2" } -#line 6009 "reflect.h2" +#line 6004 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9550,7 +9549,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6026 "reflect.h2" +#line 6021 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9558,7 +9557,7 @@ generation_function_context::generation_function_context(){} } } -#line 6033 "reflect.h2" +#line 6028 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9572,7 +9571,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6046 "reflect.h2" +#line 6041 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9588,14 +9587,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6067 "reflect.h2" +#line 6062 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6069 "reflect.h2" +#line 6064 "reflect.h2" } -#line 6071 "reflect.h2" +#line 6066 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9604,11 +9603,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6086 "reflect.h2" +#line 6081 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6088 "reflect.h2" +#line 6083 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9616,7 +9615,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6095 "reflect.h2" +#line 6090 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9625,37 +9624,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6103 "reflect.h2" +#line 6098 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6117 "reflect.h2" +#line 6112 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6121 "reflect.h2" +#line 6116 "reflect.h2" } -#line 6123 "reflect.h2" +#line 6118 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6127 "reflect.h2" +#line 6122 "reflect.h2" } -#line 6129 "reflect.h2" +#line 6124 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6133 "reflect.h2" +#line 6128 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9664,14 +9663,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6139 "reflect.h2" +#line 6134 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6144 "reflect.h2" +#line 6139 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9684,7 +9683,7 @@ size_t i{0}; } } -#line 6156 "reflect.h2" +#line 6151 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9706,7 +9705,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6177 "reflect.h2" +#line 6172 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9725,7 +9724,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6195 "reflect.h2" +#line 6190 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9741,14 +9740,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6210 "reflect.h2" +#line 6205 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6216 "reflect.h2" +#line 6211 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9756,19 +9755,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6233 "reflect.h2" +#line 6228 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6234 "reflect.h2" +#line 6229 "reflect.h2" { -#line 6239 "reflect.h2" +#line 6234 "reflect.h2" } -#line 6242 "reflect.h2" +#line 6237 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9894,7 +9893,7 @@ size_t i{0}; ); } -#line 6367 "reflect.h2" +#line 6362 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9904,13 +9903,13 @@ size_t i{0}; ); } -#line 6376 "reflect.h2" +#line 6371 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6381 "reflect.h2" +#line 6376 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9921,12 +9920,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6393 "reflect.h2" +#line 6388 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6398 "reflect.h2" +#line 6393 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9960,7 +9959,7 @@ size_t i{0}; } -#line 6434 "reflect.h2" +#line 6429 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9969,19 +9968,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6457 "reflect.h2" +#line 6452 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6458 "reflect.h2" +#line 6453 "reflect.h2" { -#line 6463 "reflect.h2" +#line 6458 "reflect.h2" } -#line 6465 "reflect.h2" +#line 6460 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10083,19 +10082,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6566 "reflect.h2" +#line 6561 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6570 "reflect.h2" +#line 6565 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6594 "reflect.h2" +#line 6589 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10114,7 +10113,7 @@ size_t i{0}; return r; } -#line 6612 "reflect.h2" +#line 6607 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10129,7 +10128,7 @@ size_t i{0}; return r; } -#line 6626 "reflect.h2" +#line 6621 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10289,7 +10288,7 @@ size_t i{0}; } } -#line 6785 "reflect.h2" +#line 6780 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10298,7 +10297,7 @@ size_t i{0}; return r; } -#line 6793 "reflect.h2" +#line 6788 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10317,7 +10316,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6811 "reflect.h2" +#line 6806 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10349,7 +10348,7 @@ size_t i{0}; } } -#line 6842 "reflect.h2" +#line 6837 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10360,7 +10359,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6854 "reflect.h2" +#line 6849 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10399,7 +10398,7 @@ size_t i{0}; return r; } -#line 6895 "reflect.h2" +#line 6890 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10417,7 +10416,7 @@ size_t i{0}; }} } -#line 6915 "reflect.h2" +#line 6910 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10431,16 +10430,16 @@ size_t i{0}; } } -#line 6941 "reflect.h2" +#line 6936 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6944 "reflect.h2" +#line 6939 "reflect.h2" } -#line 6946 "reflect.h2" +#line 6941 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10452,7 +10451,7 @@ size_t i{0}; } } -#line 6957 "reflect.h2" +#line 6952 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10460,14 +10459,14 @@ size_t i{0}; return r; } -#line 6964 "reflect.h2" +#line 6959 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6972 "reflect.h2" +#line 6967 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10493,7 +10492,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7000 "reflect.h2" +#line 6995 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10519,11 +10518,11 @@ size_t i{0}; return r; } -#line 7037 "reflect.h2" +#line 7032 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7039 "reflect.h2" +#line 7034 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10597,7 +10596,7 @@ size_t i{0}; return nullptr; } -#line 7112 "reflect.h2" +#line 7107 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10610,7 +10609,7 @@ size_t i{0}; }} } -#line 7124 "reflect.h2" +#line 7119 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10624,7 +10623,7 @@ size_t i{0}; }} } -#line 7137 "reflect.h2" +#line 7132 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10644,7 +10643,7 @@ size_t i{0}; return r; } -#line 7156 "reflect.h2" +#line 7151 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10655,7 +10654,7 @@ size_t i{0}; return r; } -#line 7166 "reflect.h2" +#line 7161 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10667,14 +10666,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7177 "reflect.h2" +#line 7172 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7189 "reflect.h2" +#line 7184 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10698,7 +10697,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7213 "reflect.h2" +#line 7208 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10708,7 +10707,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7225 "reflect.h2" +#line 7220 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10724,7 +10723,7 @@ size_t i{0}; } } -#line 7245 "reflect.h2" +#line 7240 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10742,15 +10741,15 @@ size_t i{0}; }} } -#line 7281 "reflect.h2" +#line 7276 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7284 "reflect.h2" +#line 7279 "reflect.h2" } -#line 7286 "reflect.h2" +#line 7281 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10786,7 +10785,7 @@ size_t i{0}; return source; } -#line 7321 "reflect.h2" +#line 7316 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10802,7 +10801,7 @@ size_t i{0}; } } -#line 7337 "reflect.h2" +#line 7332 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10811,7 +10810,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10866,7 +10865,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7406 "reflect.h2" +#line 7401 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10988,7 +10987,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7528 "reflect.h2" +#line 7523 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 1004bdf6a..aed326da1 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3928,21 +3928,29 @@ autodiff_special_func: type = { autodiff_context: type = { private temporary_count : int = 0; - public math_funcs : std::map = ( - std::make_pair("sin", "cos(_x_)"), - std::make_pair("cos", "-sin(_x_)"), - std::make_pair("exp", "exp(_x_)"), - // TODO: Extend - ); // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. + // _r_ : name of the return value. + // _rd_ : name of derivative return value. // _a1_ : First argument value // _ad1_: First derivative argument value // _a2_ : Second argument value // _ad2_: Second derivative argument value public special_funcs : std::vector = ( + autodiff_special_func("sin", 1, /* has_return = */ true, /* is_member = */ false, + "_rd_ = cos(_a1_) * _ad1_;\n" + "_r_ = sin(_a1_);\n" + ), + autodiff_special_func("cos", 1, /* has_return = */ true, /* is_member = */ false, + "_rd_ = -sin(_a1_) * _ad1_;\n" + "_r_ = cos(_a1_);\n" + ), + autodiff_special_func("exp", 1, /* has_return = */ true, /* is_member = */ false, + "_rd_ = exp(_a1_) * _ad1_;\n" + "_r_ = exp(_a1_);\n" + ), autodiff_special_func("push_back", 1, /* has_return = */ false, /* is_member = */ true, "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n") @@ -4146,10 +4154,6 @@ autodiff_expression_handler: type = { if handle_special_function(object, object_d, function_name, args, r_arg) { return; } - // TODO: Extend to a generalized version and not only functions with one argument. - if handle_math_func(function_name, args[0]) { - return; - } // No special handling, currently only allow direct function calls if !object.empty() { @@ -4178,20 +4182,6 @@ autodiff_expression_handler: type = { // TODO: Add function to list of functions/objects for differentiation. } - handle_math_func :(inout this, func_name: std::string, arg: std::string) -> bool = { - pos := ctx*.math_funcs.find(func_name); - - if pos == ctx*.math_funcs.end() { - return false; - } - - func_diff := string_util::replace_all(pos*.second, "_x_", arg); - - gen_lhs_assignment("(func_name)$((arg)$)", "(func_diff)$ * (arg)$_d"); - - return true; - } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector, ret: std::string) -> bool = { r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !ret.empty(), !object.empty()); @@ -4385,7 +4375,12 @@ autodiff_expression_handler: type = { } } else if primary.is_literal() { - gen_lhs_assignment(primary.to_string(), "0.0"); + // TODO: Determine propre zero initializer from type of literal. + ad_init : std::string = "()"; + if declare_d == ":" || declare_d == ": _" { + ad_init = "0.0"; + } + gen_lhs_assignment(primary.to_string(), ad_init); } else if primary.is_declaration() { primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); From 093f291fc463233c19a94ad72bd7c6a03b2329d4 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 14:51:41 +0200 Subject: [PATCH 19/54] Suffix can now be user defined. --- regression-tests/pure2-autodiff.cpp2 | 51 +- .../test-results/pure2-autodiff.cpp | 319 ++--- .../test-results/pure2-autodiff.cpp2.output | 54 +- source/reflect.h | 1101 +++++++++-------- source/reflect.h2 | 63 +- 5 files changed, 818 insertions(+), 770 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 76fcfebe3..907a08cca 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -153,6 +153,7 @@ ad_test: @autodiff @print type = { } } + write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$) = (r = (ret.r)$, r_d = (ret.r_d)$)" << std::endl; } @@ -164,29 +165,29 @@ main: () = { y: double = 3.0; y_d: double = 2.0; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_diff(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_diff(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_diff(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_diff(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_diff(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_diff(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_diff(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); - write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_diff(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_diff(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(x, x_d, y, y_d)); + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 393feaf08..94839f3e6 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -146,110 +146,110 @@ using for_loop_ret = double; #line 141 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; -struct add_1_diff_ret { double r; double r_d; }; +struct add_1_d_ret { double r; double r_d; }; - public: [[nodiscard]] static auto add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret; + public: [[nodiscard]] static auto add_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_d_ret; -struct add_2_diff_ret { double r; double r_d; }; +struct add_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret; +public: [[nodiscard]] static auto add_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_d_ret; -struct sub_1_diff_ret { double r; double r_d; }; +struct sub_1_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret; +public: [[nodiscard]] static auto sub_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_d_ret; -struct sub_2_diff_ret { double r; double r_d; }; +struct sub_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret; +public: [[nodiscard]] static auto sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_d_ret; -struct add_sub_2_diff_ret { double r; double r_d; }; +struct add_sub_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret; +public: [[nodiscard]] static auto add_sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_d_ret; -struct mul_1_diff_ret { double r; double r_d; }; +struct mul_1_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret; +public: [[nodiscard]] static auto mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_d_ret; -struct mul_2_diff_ret { double r; double r_d; }; +struct mul_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret; +public: [[nodiscard]] static auto mul_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_d_ret; -struct div_1_diff_ret { double r; double r_d; }; +struct div_1_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret; +public: [[nodiscard]] static auto div_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_d_ret; -struct div_2_diff_ret { double r; double r_d; }; +struct div_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret; +public: [[nodiscard]] static auto div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_d_ret; -struct mul_div_2_diff_ret { double r; double r_d; }; +struct mul_div_2_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret; +public: [[nodiscard]] static auto mul_div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_d_ret; -struct mul_add_diff_ret { double r; double r_d; }; +struct mul_add_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret; +public: [[nodiscard]] static auto mul_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_d_ret; -struct add_mul_diff_ret { double r; double r_d; }; +struct add_mul_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret; +public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret; -struct func_diff_ret { double r; double r_d; }; +struct func_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret; +public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret; -struct func_call_diff_ret { double r; double r_d; }; +struct func_call_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret; +public: [[nodiscard]] static auto func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret; -struct sin_call_diff_ret { double r; double r_d; }; +struct sin_call_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret; +public: [[nodiscard]] static auto sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret; -struct if_branch_diff_ret { double r; double r_d; }; +struct if_branch_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto if_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_diff_ret; +public: [[nodiscard]] static auto if_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_d_ret; -struct if_else_branch_diff_ret { double r; double r_d; }; +struct if_else_branch_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret; +public: [[nodiscard]] static auto if_else_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_d_ret; -struct direct_return_diff_ret { double r; double r_d; }; +struct direct_return_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret; +public: [[nodiscard]] static auto direct_return_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_d_ret; -struct intermediate_var_diff_ret { double r; double r_d; }; +struct intermediate_var_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret; +public: [[nodiscard]] static auto intermediate_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_d_ret; -struct intermediate_passive_var_diff_ret { double r; double r_d; }; +struct intermediate_passive_var_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto intermediate_passive_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_diff_ret; +public: [[nodiscard]] static auto intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_d_ret; -struct intermediate_untyped_diff_ret { double r; double r_d; }; +struct intermediate_untyped_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto intermediate_untyped_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_diff_ret; +public: [[nodiscard]] static auto intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_d_ret; -struct intermediate_default_init_diff_ret { double r; double r_d; }; +struct intermediate_default_init_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto intermediate_default_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_diff_ret; +public: [[nodiscard]] static auto intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_d_ret; -struct intermediate_no_init_diff_ret { double r; double r_d; }; +struct intermediate_no_init_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto intermediate_no_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_diff_ret; +public: [[nodiscard]] static auto intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_d_ret; -struct while_loop_diff_ret { double r; double r_d; }; +struct while_loop_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret; +public: [[nodiscard]] static auto while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_d_ret; -struct do_while_loop_diff_ret { double r; double r_d; }; +struct do_while_loop_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret; +public: [[nodiscard]] static auto do_while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_d_ret; -struct for_loop_diff_ret { double r; double r_d; }; +struct for_loop_d_ret { double r; double r_d; }; -public: [[nodiscard]] static auto for_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_diff_ret; +public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_d_ret; public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ @@ -259,9 +259,10 @@ public: [[nodiscard]] static auto for_loop_diff(cpp2::impl::in x, cpp2:: #line 154 "pure2-autodiff.cpp2" }; +#line 157 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 160 "pure2-autodiff.cpp2" +#line 161 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -495,85 +496,85 @@ auto main() -> int; }return std::move(r.value()); } - [[nodiscard]] auto ad_test::add_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d; + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::add_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d + x_d; + [[nodiscard]] auto ad_test::add_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d + x_d; r = x + y + x; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::sub_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d - y_d; + [[nodiscard]] auto ad_test::sub_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d; r = x - y; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d - y_d - x_d; + [[nodiscard]] auto ad_test::sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d - x_d; r = x - y - x; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::add_sub_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d - x_d; + [[nodiscard]] auto ad_test::add_sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d - x_d; r = x + y - x; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::mul_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x * y_d + y * x_d; + [[nodiscard]] auto ad_test::mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x * y_d + y * x_d; r = x * y; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::mul_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::mul_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); r = cpp2::move(temp_1) * x; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::div_1_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + [[nodiscard]] auto ad_test::div_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::mul_div_2_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::mul_div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::mul_add_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x_d + y_d}; auto temp_1 {x + y}; @@ -582,9 +583,9 @@ auto temp_1_d {x_d + y_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::add_mul_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; auto temp_1 {x * y}; @@ -593,17 +594,17 @@ auto temp_1_d {x * y_d + y * x_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::func_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d; + [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::func_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_diff_ret{ - double r {0.0}; - double r_d {0.0}; -auto temp_2 {func_diff(x, x_d, y, y_d)}; + [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_2 {func_d(x, x_d, y, y_d)}; auto temp_1 {temp_2.r}; @@ -613,9 +614,9 @@ auto temp_2 {func_diff(x, x_d, y, y_d)}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::sin_call_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret{ + double r {0.0}; + double r_d {0.0}; auto temp_1_d {x_d - y_d}; auto temp_1 {x - y}; @@ -624,9 +625,9 @@ auto temp_1_d {x_d - y_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::if_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d; + [[nodiscard]] auto ad_test::if_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x_d; r = x; if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; @@ -637,9 +638,9 @@ auto temp_1_d {x_d - y_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::if_else_branch_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_diff_ret{ - double r {0.0}; - double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { + [[nodiscard]] auto ad_test::if_else_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_d_ret{ + double r {0.0}; + double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; r = y; } @@ -650,15 +651,15 @@ auto temp_1_d {x_d - y_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::direct_return_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_diff_ret{ - double r {}; - double r_d {};r_d = x_d + y_d; + [[nodiscard]] auto ad_test::direct_return_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_d_ret{ + double r {}; + double r_d {};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::intermediate_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::intermediate_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_d_ret{ + double r {0.0}; + double r_d {0.0}; double t_d {x_d + y_d}; double t {x + y}; @@ -667,9 +668,9 @@ double t_d {x_d + y_d}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::intermediate_passive_var_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_d_ret{ + double r {0.0}; + double r_d {0.0}; int i_d {}; int i {}; @@ -682,9 +683,9 @@ int i_d {}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::intermediate_untyped_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_d_ret{ + double r {0.0}; + double r_d {0.0}; auto t_d {0.0}; auto t {0.0}; @@ -695,9 +696,9 @@ auto t_d {0.0}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::intermediate_default_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_d_ret{ + double r {0.0}; + double r_d {0.0}; double t_d {}; double t {}; @@ -708,9 +709,9 @@ double t_d {}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::intermediate_no_init_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_diff_ret{ - double r {0.0}; - double r_d {0.0};r_d = { }; + [[nodiscard]] auto ad_test::intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = { }; r = 0.0; cpp2::impl::deferred_init t_d; @@ -723,9 +724,9 @@ double t_d {}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_d_ret{ + double r {0.0}; + double r_d {0.0}; int i_d {}; int i {0}; @@ -738,9 +739,9 @@ int i_d {}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::do_while_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::do_while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_d_ret{ + double r {0.0}; + double r_d {0.0}; int i_d {}; int i {0}; @@ -758,9 +759,9 @@ int i_d {}; return { std::move(r), std::move(r_d) }; } - [[nodiscard]] auto ad_test::for_loop_diff(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_diff_ret{ - double r {0.0}; - double r_d {0.0}; + [[nodiscard]] auto ad_test::for_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_d_ret{ + double r {0.0}; + double r_d {0.0}; std::vector v_d {}; std::vector v {}; @@ -786,12 +787,12 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 156 "pure2-autodiff.cpp2" +#line 157 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 160 "pure2-autodiff.cpp2" +#line 161 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -799,30 +800,30 @@ auto main() -> int{ double y {3.0}; double y_d {2.0}; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_diff(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_diff(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_diff(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_diff(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_diff(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_diff(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_diff(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_diff(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_diff(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_diff(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_diff(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_diff(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_diff(x, x_d, y, y_d)); - write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_diff(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_diff(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_diff(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_diff(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_diff(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_diff(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_diff(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_diff(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_diff(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_diff(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_diff(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_diff(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 7e730409e..6d8d50fbe 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -278,7 +278,7 @@ ad_test:/* @autodiff @print */ type = return; } - add_1_diff:( + add_1_d:( in x: double, in x_d: double, in y: double, @@ -293,7 +293,7 @@ ad_test:/* @autodiff @print */ type = return; } - add_2_diff:( + add_2_d:( in x: double, in x_d: double, in y: double, @@ -308,7 +308,7 @@ ad_test:/* @autodiff @print */ type = return; } - sub_1_diff:( + sub_1_d:( in x: double, in x_d: double, in y: double, @@ -323,7 +323,7 @@ ad_test:/* @autodiff @print */ type = return; } - sub_2_diff:( + sub_2_d:( in x: double, in x_d: double, in y: double, @@ -338,7 +338,7 @@ ad_test:/* @autodiff @print */ type = return; } - add_sub_2_diff:( + add_sub_2_d:( in x: double, in x_d: double, in y: double, @@ -353,7 +353,7 @@ ad_test:/* @autodiff @print */ type = return; } - mul_1_diff:( + mul_1_d:( in x: double, in x_d: double, in y: double, @@ -368,7 +368,7 @@ ad_test:/* @autodiff @print */ type = return; } - mul_2_diff:( + mul_2_d:( in x: double, in x_d: double, in y: double, @@ -385,7 +385,7 @@ ad_test:/* @autodiff @print */ type = return; } - div_1_diff:( + div_1_d:( in x: double, in x_d: double, in y: double, @@ -400,7 +400,7 @@ ad_test:/* @autodiff @print */ type = return; } - div_2_diff:( + div_2_d:( in x: double, in x_d: double, in y: double, @@ -417,7 +417,7 @@ ad_test:/* @autodiff @print */ type = return; } - mul_div_2_diff:( + mul_div_2_d:( in x: double, in x_d: double, in y: double, @@ -434,7 +434,7 @@ ad_test:/* @autodiff @print */ type = return; } - mul_add_diff:( + mul_add_d:( in x: double, in x_d: double, in y: double, @@ -451,7 +451,7 @@ ad_test:/* @autodiff @print */ type = return; } - add_mul_diff:( + add_mul_d:( in x: double, in x_d: double, in y: double, @@ -468,7 +468,7 @@ ad_test:/* @autodiff @print */ type = return; } - func_diff:( + func_d:( in x: double, in x_d: double, in y: double, @@ -483,7 +483,7 @@ ad_test:/* @autodiff @print */ type = return; } - func_call_diff:( + func_call_d:( in x: double, in x_d: double, in y: double, @@ -493,7 +493,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_2: _ = func_diff(x, x_d, y, y_d); + temp_2: _ = func_d(x, x_d, y, y_d); temp_1: _ = temp_2.r; temp_1_d: _ = temp_2.r_d; r_d = x * temp_1_d + temp_1 * x_d; @@ -501,7 +501,7 @@ ad_test:/* @autodiff @print */ type = return; } - sin_call_diff:( + sin_call_d:( in x: double, in x_d: double, in y: double, @@ -518,7 +518,7 @@ ad_test:/* @autodiff @print */ type = return; } - if_branch_diff:( + if_branch_d:( in x: double, in x_d: double, in y: double, @@ -541,7 +541,7 @@ ad_test:/* @autodiff @print */ type = return; } - if_else_branch_diff:( + if_else_branch_d:( in x: double, in x_d: double, in y: double, @@ -564,7 +564,7 @@ ad_test:/* @autodiff @print */ type = return; } - direct_return_diff:( + direct_return_d:( in x: double, in x_d: double, in y: double, @@ -579,7 +579,7 @@ ad_test:/* @autodiff @print */ type = return; } - intermediate_var_diff:( + intermediate_var_d:( in x: double, in x_d: double, in y: double, @@ -596,7 +596,7 @@ ad_test:/* @autodiff @print */ type = return; } - intermediate_passive_var_diff:( + intermediate_passive_var_d:( in x: double, in x_d: double, in y: double, @@ -617,7 +617,7 @@ ad_test:/* @autodiff @print */ type = return; } - intermediate_untyped_diff:( + intermediate_untyped_d:( in x: double, in x_d: double, in y: double, @@ -636,7 +636,7 @@ ad_test:/* @autodiff @print */ type = return; } - intermediate_default_init_diff:( + intermediate_default_init_d:( in x: double, in x_d: double, in y: double, @@ -655,7 +655,7 @@ ad_test:/* @autodiff @print */ type = return; } - intermediate_no_init_diff:( + intermediate_no_init_d:( in x: double, in x_d: double, in y: double, @@ -676,7 +676,7 @@ ad_test:/* @autodiff @print */ type = return; } - while_loop_diff:( + while_loop_d:( in x: double, in x_d: double, in y: double, @@ -699,7 +699,7 @@ ad_test:/* @autodiff @print */ type = return; } - do_while_loop_diff:( + do_while_loop_d:( in x: double, in x_d: double, in y: double, @@ -723,7 +723,7 @@ ad_test:/* @autodiff @print */ type = return; } - for_loop_diff:( + for_loop_d:( in x: double, in x_d: double, in y: double, diff --git a/source/reflect.h b/source/reflect.h index 01c963548..e98e97c20 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -109,88 +109,88 @@ class autodiff_special_func; class autodiff_context; -#line 3987 "reflect.h2" +#line 3989 "reflect.h2" class autodiff_handler_base; -#line 4001 "reflect.h2" +#line 4003 "reflect.h2" class autodiff_expression_handler; -#line 4394 "reflect.h2" +#line 4396 "reflect.h2" class autodiff_stmt_handler; -#line 5101 "reflect.h2" +#line 5124 "reflect.h2" class expression_flags; -#line 5117 "reflect.h2" +#line 5140 "reflect.h2" class regex_token; -#line 5144 "reflect.h2" +#line 5167 "reflect.h2" class regex_token_check; -#line 5165 "reflect.h2" +#line 5188 "reflect.h2" class regex_token_code; -#line 5186 "reflect.h2" +#line 5209 "reflect.h2" class regex_token_empty; -#line 5204 "reflect.h2" +#line 5227 "reflect.h2" class regex_token_list; -#line 5256 "reflect.h2" +#line 5279 "reflect.h2" class parse_context_group_state; -#line 5317 "reflect.h2" +#line 5340 "reflect.h2" class parse_context_branch_reset_state; -#line 5360 "reflect.h2" +#line 5383 "reflect.h2" class parse_context; -#line 5761 "reflect.h2" +#line 5784 "reflect.h2" class generation_function_context; -#line 5779 "reflect.h2" +#line 5802 "reflect.h2" class generation_context; -#line 5978 "reflect.h2" +#line 6001 "reflect.h2" class alternative_token; -#line 5993 "reflect.h2" +#line 6016 "reflect.h2" class alternative_token_gen; -#line 6058 "reflect.h2" +#line 6081 "reflect.h2" class any_token; -#line 6075 "reflect.h2" +#line 6098 "reflect.h2" class atomic_group_token; -#line 6105 "reflect.h2" +#line 6128 "reflect.h2" class char_token; -#line 6220 "reflect.h2" +#line 6243 "reflect.h2" class class_token; -#line 6444 "reflect.h2" +#line 6467 "reflect.h2" class group_ref_token; -#line 6581 "reflect.h2" +#line 6604 "reflect.h2" class group_token; -#line 6928 "reflect.h2" +#line 6951 "reflect.h2" class lookahead_lookbehind_token; -#line 7023 "reflect.h2" +#line 7046 "reflect.h2" class range_token; -#line 7180 "reflect.h2" +#line 7203 "reflect.h2" class special_range_token; -#line 7266 "reflect.h2" +#line 7289 "reflect.h2" template class regex_generator; -#line 7523 "reflect.h2" +#line 7546 "reflect.h2" } } @@ -1641,22 +1641,24 @@ class autodiff_context { "_od_.push_back(_ad1_);\n")}; #line 3959 "reflect.h2" + public: std::string suffix {"_d"}; + public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 3965 "reflect.h2" +#line 3967 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 3972 "reflect.h2" +#line 3974 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 3985 "reflect.h2" +#line 3987 "reflect.h2" }; class autodiff_handler_base { @@ -1665,21 +1667,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 3992 "reflect.h2" +#line 3994 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 3996 "reflect.h2" +#line 3998 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 3999 "reflect.h2" +#line 4001 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4005 "reflect.h2" +#line 4007 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1688,180 +1690,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4022 "reflect.h2" +#line 4024 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4041 "reflect.h2" +#line 4043 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4050 "reflect.h2" +#line 4052 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4088 "reflect.h2" +#line 4090 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4185 "reflect.h2" +#line 4187 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4218 "reflect.h2" +#line 4220 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4222 "reflect.h2" +#line 4224 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4226 "reflect.h2" +#line 4228 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4230 "reflect.h2" +#line 4232 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4234 "reflect.h2" +#line 4236 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4238 "reflect.h2" +#line 4240 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4242 "reflect.h2" +#line 4244 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4246 "reflect.h2" +#line 4248 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4250 "reflect.h2" +#line 4252 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4254 "reflect.h2" +#line 4256 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4258 "reflect.h2" +#line 4260 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4262 "reflect.h2" +#line 4264 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4285 "reflect.h2" +#line 4287 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4328 "reflect.h2" +#line 4330 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4332 "reflect.h2" +#line 4334 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4337 "reflect.h2" +#line 4339 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4364 "reflect.h2" +#line 4366 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4392 "reflect.h2" +#line 4394 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4398 "reflect.h2" +#line 4400 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4407 "reflect.h2" +#line 4409 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4412 "reflect.h2" +#line 4414 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4417 "reflect.h2" +#line 4419 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4435 "reflect.h2" +#line 4437 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4440 "reflect.h2" +#line 4442 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4445 "reflect.h2" +#line 4447 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4450 "reflect.h2" +#line 4452 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4458 "reflect.h2" +#line 4460 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4474 "reflect.h2" +#line 4476 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4521 "reflect.h2" +#line 4523 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4532 "reflect.h2" +#line 4534 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4560 "reflect.h2" +#line 4562 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4565 "reflect.h2" +#line 4567 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4569 "reflect.h2" +#line 4571 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4573 "reflect.h2" +#line 4575 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4577 "reflect.h2" +#line 4579 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4581 "reflect.h2" +#line 4583 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4585 "reflect.h2" +#line 4587 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4589 "reflect.h2" +#line 4591 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4593 "reflect.h2" +#line 4595 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4597 "reflect.h2" +#line 4599 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4601 "reflect.h2" +#line 4603 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4605 "reflect.h2" +#line 4607 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4609 "reflect.h2" +#line 4611 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4613 "reflect.h2" +#line 4615 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4618 "reflect.h2" +#line 4620 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4647 "reflect.h2" +#line 4649 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4651 "reflect.h2" +#line 4653 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 5097 "reflect.h2" +#line 5120 "reflect.h2" using error_func = std::function x)>; -#line 5101 "reflect.h2" +#line 5124 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1896,20 +1898,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5109 "reflect.h2" +#line 5132 "reflect.h2" }; -#line 5117 "reflect.h2" +#line 5140 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5125 "reflect.h2" +#line 5148 "reflect.h2" public: explicit regex_token(); -#line 5130 "reflect.h2" +#line 5153 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1921,103 +1923,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5136 "reflect.h2" +#line 5159 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5142 "reflect.h2" +#line 5165 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5148 "reflect.h2" +#line 5171 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5155 "reflect.h2" +#line 5178 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5159 "reflect.h2" +#line 5182 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5160 "reflect.h2" +#line 5183 "reflect.h2" }; -#line 5163 "reflect.h2" +#line 5186 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5169 "reflect.h2" +#line 5192 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5176 "reflect.h2" +#line 5199 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5180 "reflect.h2" +#line 5203 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5181 "reflect.h2" +#line 5204 "reflect.h2" }; -#line 5184 "reflect.h2" +#line 5207 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5190 "reflect.h2" +#line 5213 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5194 "reflect.h2" +#line 5217 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5198 "reflect.h2" +#line 5221 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5199 "reflect.h2" +#line 5222 "reflect.h2" }; -#line 5202 "reflect.h2" +#line 5225 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5208 "reflect.h2" +#line 5231 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5215 "reflect.h2" +#line 5238 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5221 "reflect.h2" +#line 5244 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5227 "reflect.h2" +#line 5250 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5235 "reflect.h2" +#line 5258 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2025,10 +2027,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5247 "reflect.h2" +#line 5270 "reflect.h2" }; -#line 5250 "reflect.h2" +#line 5273 "reflect.h2" // // Parse and generation context. // @@ -2044,33 +2046,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5270 "reflect.h2" +#line 5293 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5277 "reflect.h2" +#line 5300 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5289 "reflect.h2" +#line 5312 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5294 "reflect.h2" +#line 5317 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5298 "reflect.h2" +#line 5321 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5312 "reflect.h2" +#line 5335 "reflect.h2" }; -#line 5315 "reflect.h2" +#line 5338 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2083,25 +2085,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5333 "reflect.h2" +#line 5356 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5339 "reflect.h2" +#line 5362 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5346 "reflect.h2" +#line 5369 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5353 "reflect.h2" +#line 5376 "reflect.h2" }; -#line 5356 "reflect.h2" +#line 5379 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2117,7 +2119,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5372 "reflect.h2" +#line 5395 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2125,64 +2127,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5383 "reflect.h2" +#line 5406 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5396 "reflect.h2" +#line 5419 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5404 "reflect.h2" +#line 5427 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5408 "reflect.h2" +#line 5431 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5412 "reflect.h2" +#line 5435 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5424 "reflect.h2" +#line 5447 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5431 "reflect.h2" +#line 5454 "reflect.h2" public: auto next_alternative() & -> void; -#line 5437 "reflect.h2" +#line 5460 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5443 "reflect.h2" +#line 5466 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5447 "reflect.h2" +#line 5470 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5458 "reflect.h2" +#line 5481 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5462 "reflect.h2" +#line 5485 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5468 "reflect.h2" +#line 5491 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5472 "reflect.h2" +#line 5495 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5479 "reflect.h2" +#line 5502 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5490 "reflect.h2" +#line 5513 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2190,51 +2192,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5534 "reflect.h2" +#line 5557 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5546 "reflect.h2" +#line 5569 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5559 "reflect.h2" +#line 5582 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5582 "reflect.h2" +#line 5605 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5599 "reflect.h2" +#line 5622 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5620 "reflect.h2" +#line 5643 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5630 "reflect.h2" +#line 5653 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5634 "reflect.h2" +#line 5657 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5690 "reflect.h2" +#line 5713 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5729 "reflect.h2" +#line 5752 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5744 "reflect.h2" +#line 5767 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2246,10 +2248,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5755 "reflect.h2" +#line 5778 "reflect.h2" }; -#line 5758 "reflect.h2" +#line 5781 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2259,16 +2261,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5772 "reflect.h2" +#line 5795 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5775 "reflect.h2" +#line 5798 "reflect.h2" }; -#line 5778 "reflect.h2" +#line 5801 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2288,68 +2290,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5800 "reflect.h2" +#line 5823 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5806 "reflect.h2" +#line 5829 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5815 "reflect.h2" +#line 5838 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5826 "reflect.h2" +#line 5849 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5833 "reflect.h2" +#line 5856 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5853 "reflect.h2" +#line 5876 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5863 "reflect.h2" +#line 5886 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5886 "reflect.h2" +#line 5909 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5894 "reflect.h2" +#line 5917 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5898 "reflect.h2" +#line 5921 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5904 "reflect.h2" +#line 5927 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5910 "reflect.h2" +#line 5933 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5920 "reflect.h2" +#line 5943 "reflect.h2" public: auto finish_context() & -> void; -#line 5928 "reflect.h2" +#line 5951 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5934 "reflect.h2" +#line 5957 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5938 "reflect.h2" +#line 5961 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5942 "reflect.h2" +#line 5965 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5966 "reflect.h2" +#line 5989 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2357,7 +2359,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5972 "reflect.h2" +#line 5995 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2377,27 +2379,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5991 "reflect.h2" +#line 6014 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5997 "reflect.h2" +#line 6020 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6004 "reflect.h2" +#line 6027 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6021 "reflect.h2" +#line 6044 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6028 "reflect.h2" +#line 6051 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6041 "reflect.h2" +#line 6064 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2405,19 +2407,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6053 "reflect.h2" +#line 6076 "reflect.h2" }; -#line 6056 "reflect.h2" +#line 6079 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6062 "reflect.h2" +#line 6085 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6066 "reflect.h2" +#line 6089 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2425,7 +2427,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6071 "reflect.h2" +#line 6094 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2433,17 +2435,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6079 "reflect.h2" +#line 6102 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6090 "reflect.h2" +#line 6113 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6098 "reflect.h2" +#line 6121 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2451,7 +2453,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6101 "reflect.h2" +#line 6124 "reflect.h2" }; // Regex syntax: a @@ -2459,34 +2461,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6109 "reflect.h2" +#line 6132 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6118 "reflect.h2" +#line 6141 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6124 "reflect.h2" +#line 6147 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6128 "reflect.h2" +#line 6151 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6151 "reflect.h2" +#line 6174 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6172 "reflect.h2" +#line 6195 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6190 "reflect.h2" +#line 6213 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6205 "reflect.h2" +#line 6228 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6211 "reflect.h2" +#line 6234 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2494,33 +2496,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6215 "reflect.h2" +#line 6238 "reflect.h2" }; -#line 6218 "reflect.h2" +#line 6241 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6224 "reflect.h2" +#line 6247 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6236 "reflect.h2" +#line 6259 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6362 "reflect.h2" +#line 6385 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6371 "reflect.h2" +#line 6394 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6376 "reflect.h2" +#line 6399 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2528,20 +2530,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6383 "reflect.h2" +#line 6406 "reflect.h2" }; -#line 6386 "reflect.h2" +#line 6409 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6427 "reflect.h2" +#line 6450 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6438 "reflect.h2" +#line 6461 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2551,20 +2553,20 @@ class class_token class group_ref_token : public regex_token { -#line 6448 "reflect.h2" +#line 6471 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6460 "reflect.h2" +#line 6483 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6561 "reflect.h2" +#line 6584 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6565 "reflect.h2" +#line 6588 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2572,10 +2574,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6568 "reflect.h2" +#line 6591 "reflect.h2" }; -#line 6571 "reflect.h2" +#line 6594 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2589,29 +2591,29 @@ class group_ref_token class group_token : public regex_token { -#line 6585 "reflect.h2" +#line 6608 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6607 "reflect.h2" +#line 6630 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6621 "reflect.h2" +#line 6644 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6780 "reflect.h2" +#line 6803 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6788 "reflect.h2" +#line 6811 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6806 "reflect.h2" +#line 6829 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6837 "reflect.h2" +#line 6860 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2620,25 +2622,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6844 "reflect.h2" +#line 6867 "reflect.h2" }; -#line 6847 "reflect.h2" +#line 6870 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6888 "reflect.h2" +#line 6911 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6908 "reflect.h2" +#line 6931 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6924 "reflect.h2" +#line 6947 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2646,20 +2648,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6932 "reflect.h2" +#line 6955 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6941 "reflect.h2" +#line 6964 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6952 "reflect.h2" +#line 6975 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6959 "reflect.h2" +#line 6982 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2667,26 +2669,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6962 "reflect.h2" +#line 6985 "reflect.h2" }; -#line 6965 "reflect.h2" +#line 6988 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6993 "reflect.h2" +#line 7016 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7021 "reflect.h2" +#line 7044 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7027 "reflect.h2" +#line 7050 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2696,22 +2698,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7107 "reflect.h2" +#line 7130 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7119 "reflect.h2" +#line 7142 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7132 "reflect.h2" +#line 7155 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7151 "reflect.h2" +#line 7174 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7161 "reflect.h2" +#line 7184 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7172 "reflect.h2" +#line 7195 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2719,16 +2721,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7175 "reflect.h2" +#line 7198 "reflect.h2" }; -#line 7178 "reflect.h2" +#line 7201 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7184 "reflect.h2" +#line 7207 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2737,7 +2739,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7214 "reflect.h2" +#line 7237 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2746,14 +2748,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7236 "reflect.h2" +#line 7259 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7258 "reflect.h2" +#line 7281 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2774,24 +2776,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7281 "reflect.h2" +#line 7304 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7316 "reflect.h2" +#line 7339 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7330 "reflect.h2" +#line 7353 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7342 "reflect.h2" +#line 7365 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7397 "reflect.h2" +#line 7420 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2802,7 +2804,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7523 "reflect.h2" +#line 7546 "reflect.h2" } } @@ -7374,14 +7376,14 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 3954 "reflect.h2" /* has_return = */ /* is_member = */ -#line 3959 "reflect.h2" +#line 3961 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 3965 "reflect.h2" +#line 3967 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ // TODO: Add type to required generation for AD. @@ -7389,11 +7391,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return type; // Use the same type for now. } -#line 3972 "reflect.h2" +#line 3974 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 3973 "reflect.h2" +#line 3975 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7407,27 +7409,27 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return { std::move(m.value()), std::move(code.value()) }; } -#line 3992 "reflect.h2" +#line 3994 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 3994 "reflect.h2" +#line 3996 "reflect.h2" } -#line 3992 "reflect.h2" +#line 3994 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 3994 "reflect.h2" +#line 3996 "reflect.h2" } -#line 3996 "reflect.h2" +#line 3998 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4011 "reflect.h2" +#line 4013 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7435,15 +7437,15 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4017 "reflect.h2" +#line 4019 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4022 "reflect.h2" +#line 4024 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ - std::string lhs_d {lhs + "_d"}; + std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { // TODO: Maybe improve discard handling lhs_d = lhs; @@ -7461,7 +7463,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4041 "reflect.h2" +#line 4043 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7471,7 +7473,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4050 "reflect.h2" +#line 4052 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7510,7 +7512,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4088 "reflect.h2" +#line 4090 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7518,7 +7520,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4094 "reflect.h2" +#line 4096 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7532,7 +7534,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4106 "reflect.h2" +#line 4108 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7547,7 +7549,7 @@ auto i{0}; if (1 != CPP2_UFCS(ssize)(terms)) { object = CPP2_UFCS(to_string)(primary); - object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + "_d"; + object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + (*cpp2::impl::assert_not_null(ctx)).suffix; } else { function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); @@ -7555,7 +7557,7 @@ auto i{0}; { auto i{0}; -#line 4127 "reflect.h2" +#line 4129 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7580,7 +7582,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4150 "reflect.h2" +#line 4152 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7602,21 +7604,21 @@ auto i{0}; } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. - diff += "" + cpp2::to_string(cpp2::move(function_name)) + "_diff("; + diff += "" + cpp2::to_string(cpp2::move(function_name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "("; for ( auto const& arg : cpp2::move(args) ) { - diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + "_d,"; + diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ","; } diff += ");\n"; if (has_return) { // TODO: Look up return value name of function. - gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r_d", true);/* switch order = */ + gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "", true);/* switch order = */ } // TODO: Add function to list of functions/objects for differentiation. } -#line 4185 "reflect.h2" +#line 4187 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7636,80 +7638,80 @@ auto i{0}; if (!(CPP2_UFCS(empty)(ret))) { code = string_util::replace_all(code, "_r_", ret); - code = string_util::replace_all(code, "_rd_", ret + "_d"); + code = string_util::replace_all(code, "_rd_", ret + (*cpp2::impl::assert_not_null(ctx)).suffix); } { auto i{1}; -#line 4208 "reflect.h2" +#line 4210 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); - code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + "_d"); + code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4213 "reflect.h2" +#line 4215 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4218 "reflect.h2" +#line 4220 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4222 "reflect.h2" +#line 4224 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4226 "reflect.h2" +#line 4228 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4230 "reflect.h2" +#line 4232 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4234 "reflect.h2" +#line 4236 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4238 "reflect.h2" +#line 4240 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4242 "reflect.h2" +#line 4244 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4246 "reflect.h2" +#line 4248 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4250 "reflect.h2" +#line 4252 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4254 "reflect.h2" +#line 4256 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4258 "reflect.h2" +#line 4260 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4262 "reflect.h2" +#line 4264 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7724,7 +7726,7 @@ auto i{1}; } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; - fwd += "" + cpp2::to_string(var) + "_d"; + fwd += "" + cpp2::to_string(var) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""; primal += "" + cpp2::to_string(cpp2::move(var)) + ""; first = false; @@ -7733,7 +7735,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4285 "reflect.h2" +#line 4287 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7749,18 +7751,18 @@ auto i{1}; std::string primal {""}; if ("*" == op) { - fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a) + "_d"; + fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""; primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; } else {if ("/" == op) { - fwd = "" + cpp2::to_string(arg_a) + "_d / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + "_d / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + fwd = "" + cpp2::to_string(arg_a) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; } else { CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4312 "reflect.h2" +#line 4314 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7769,7 +7771,7 @@ auto i{1}; // Temporary auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; // TODO: Get type of expression, in order to define the type of t. - diff += "" + cpp2::to_string(t) + "_d := " + cpp2::to_string(cpp2::move(fwd)) + ";"; + diff += "" + cpp2::to_string(t) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " := " + cpp2::to_string(cpp2::move(fwd)) + ";"; diff += "" + cpp2::to_string(t) + " := " + cpp2::to_string(cpp2::move(primal)) + ";"; arg_a = cpp2::move(t); @@ -7777,18 +7779,18 @@ auto i{1}; } } -#line 4328 "reflect.h2" +#line 4330 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4332 "reflect.h2" +#line 4334 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4337 "reflect.h2" +#line 4339 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7797,7 +7799,7 @@ auto i{1}; { auto i{0}; -#line 4344 "reflect.h2" +#line 4346 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7811,7 +7813,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4356 "reflect.h2" +#line 4358 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7820,11 +7822,11 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4364 "reflect.h2" +#line 4366 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { - gen_lhs_assignment(CPP2_UFCS(to_string)(primary), CPP2_UFCS(to_string)(primary) + "_d"); + gen_lhs_assignment(CPP2_UFCS(to_string)(primary), CPP2_UFCS(to_string)(primary) + (*cpp2::impl::assert_not_null(ctx)).suffix); } else {if (CPP2_UFCS(is_expression_list)(primary)) { if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { @@ -7850,26 +7852,26 @@ auto i{0}; }}}} } -#line 4402 "reflect.h2" +#line 4404 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4405 "reflect.h2" +#line 4407 "reflect.h2" } -#line 4407 "reflect.h2" +#line 4409 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4412 "reflect.h2" +#line 4414 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4417 "reflect.h2" +#line 4419 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7882,27 +7884,27 @@ auto i{0}; append(cpp2::move(ad)); } else { - diff += "" + cpp2::to_string(lhs) + "_d : " + cpp2::to_string(cpp2::move(ad_type)) + ";\n"; + diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(cpp2::move(ad_type)) + ";\n"; diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + ";\n"; } } -#line 4435 "reflect.h2" +#line 4437 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4440 "reflect.h2" +#line 4442 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4445 "reflect.h2" +#line 4447 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4450 "reflect.h2" +#line 4452 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -7910,7 +7912,7 @@ auto i{0}; diff += "}\n"; } -#line 4458 "reflect.h2" +#line 4460 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -7926,7 +7928,7 @@ auto i{0}; } } -#line 4474 "reflect.h2" +#line 4476 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -7959,7 +7961,7 @@ auto i{0}; auto param {CPP2_UFCS(get_for_parameter)(stmt)}; auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; - diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + "_d.begin())\n"; + diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ".begin())\n"; diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; if (CPP2_UFCS(has_next)(stmt)) { // TODO: Assumption is here that nothing is in the next expression @@ -7967,13 +7969,13 @@ auto i{0}; } diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; - diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d: " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; pre_traverse(CPP2_UFCS(get_for_body)(stmt)); diff += "}\n"; }} } -#line 4521 "reflect.h2" +#line 4523 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -7985,7 +7987,7 @@ auto i{0}; } } -#line 4532 "reflect.h2" +#line 4534 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8014,79 +8016,79 @@ auto i{0}; } } -#line 4560 "reflect.h2" +#line 4562 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4565 "reflect.h2" +#line 4567 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4569 "reflect.h2" +#line 4571 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4573 "reflect.h2" +#line 4575 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4577 "reflect.h2" +#line 4579 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4581 "reflect.h2" +#line 4583 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4585 "reflect.h2" +#line 4587 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4589 "reflect.h2" +#line 4591 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4593 "reflect.h2" +#line 4595 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4597 "reflect.h2" +#line 4599 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4601 "reflect.h2" +#line 4603 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4605 "reflect.h2" +#line 4607 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4609 "reflect.h2" +#line 4611 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4613 "reflect.h2" +#line 4615 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4618 "reflect.h2" +#line 4620 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8095,7 +8097,7 @@ auto i{0}; { auto i{0}; -#line 4625 "reflect.h2" +#line 4627 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8109,7 +8111,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4637 "reflect.h2" +#line 4639 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8120,29 +8122,49 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4647 "reflect.h2" +#line 4649 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4653 "reflect.h2" +#line 4655 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { + + std::string_view constexpr suffix_token{ "suffix=" }; + + auto args {CPP2_UFCS(get_arguments)(t)}; + + std::string suffix {"_d"}; + for ( auto const& arg_str : cpp2::move(args) ) { + if (CPP2_UFCS(starts_with)(arg_str, "\"") && CPP2_UFCS(ends_with)(arg_str, "\"")) { + auto arg {CPP2_UFCS(substr)(arg_str, 1, CPP2_UFCS(ssize)(arg_str) - 2)}; + + if (CPP2_UFCS(starts_with)(arg, suffix_token)) { + suffix = CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(suffix_token)); + continue; + } + } + + CPP2_UFCS(error)(t, "AD: Unknown argument: " + cpp2::to_string(arg_str) + ""); + return ; + } + for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_function)(m)) { auto mf {CPP2_UFCS(as_function)(m)}; - std::string diff {" " + cpp2::to_string(CPP2_UFCS(name)(mf)) + "_diff: ("}; + std::string diff {" " + cpp2::to_string(CPP2_UFCS(name)(mf)) + cpp2::to_string(suffix) + ": ("}; // 1. Generate the modified signature // a) Parameters for ( auto const& param : CPP2_UFCS(get_parameters)(mf) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; } diff += ") -> ("; @@ -8153,16 +8175,16 @@ auto autodiff(meta::type_declaration& t) -> void // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if (CPP2_UFCS(has_deduced_return_type)(mf)) { // TODO: Take care of initialization order error. - diff += "r, r_d, "; + diff += "r, r" + cpp2::to_string(suffix) + ", "; } else { - diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r_d: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), "; + diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r" + cpp2::to_string(suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), "; } } else { for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + "_d : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; } } @@ -8176,9 +8198,10 @@ auto autodiff(meta::type_declaration& t) -> void } autodiff_context ad_ctx {}; + ad_ctx.suffix = suffix; autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4705 "reflect.h2" +#line 4728 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8282,7 +8305,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4718 "reflect.h2" +#line 4741 "reflect.h2" ////----------------------------------------------------------------------- //// //// autodiff - stub @@ -8647,7 +8670,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // } //} -#line 5083 "reflect.h2" +#line 5106 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8663,11 +8686,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5099 "reflect.h2" +#line 5122 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5103 "reflect.h2" +#line 5126 "reflect.h2" // mod: i // mod: m // mod: s @@ -8675,116 +8698,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5112 "reflect.h2" +#line 5135 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5121 "reflect.h2" +#line 5144 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5123 "reflect.h2" +#line 5146 "reflect.h2" } -#line 5125 "reflect.h2" +#line 5148 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5127 "reflect.h2" +#line 5150 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5133 "reflect.h2" +#line 5156 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5134 "reflect.h2" +#line 5157 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5135 "reflect.h2" +#line 5158 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5150 "reflect.h2" +#line 5173 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5153 "reflect.h2" +#line 5176 "reflect.h2" } -#line 5155 "reflect.h2" +#line 5178 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5159 "reflect.h2" +#line 5182 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5171 "reflect.h2" +#line 5194 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5174 "reflect.h2" +#line 5197 "reflect.h2" } -#line 5176 "reflect.h2" +#line 5199 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5180 "reflect.h2" +#line 5203 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5190 "reflect.h2" +#line 5213 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5192 "reflect.h2" +#line 5215 "reflect.h2" } -#line 5194 "reflect.h2" +#line 5217 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5198 "reflect.h2" +#line 5221 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5210 "reflect.h2" +#line 5233 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5213 "reflect.h2" +#line 5236 "reflect.h2" } -#line 5215 "reflect.h2" +#line 5238 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5221 "reflect.h2" +#line 5244 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5227 "reflect.h2" +#line 5250 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8793,7 +8816,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5235 "reflect.h2" +#line 5258 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8809,7 +8832,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5263 "reflect.h2" +#line 5286 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8817,14 +8840,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5271 "reflect.h2" +#line 5294 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5278 "reflect.h2" +#line 5301 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8836,15 +8859,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5290 "reflect.h2" +#line 5313 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5295 "reflect.h2" +#line 5318 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5299 "reflect.h2" +#line 5322 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8865,7 +8888,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5325 "reflect.h2" +#line 5348 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8874,20 +8897,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5334 "reflect.h2" +#line 5357 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5340 "reflect.h2" +#line 5363 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5347 "reflect.h2" +#line 5370 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8902,16 +8925,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5377 "reflect.h2" +#line 5400 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5381 "reflect.h2" +#line 5404 "reflect.h2" } -#line 5387 "reflect.h2" +#line 5410 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8921,7 +8944,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5397 "reflect.h2" +#line 5420 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8929,17 +8952,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5404 "reflect.h2" +#line 5427 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5408 "reflect.h2" +#line 5431 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5415 "reflect.h2" +#line 5438 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8949,7 +8972,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5424 "reflect.h2" +#line 5447 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8957,24 +8980,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5431 "reflect.h2" +#line 5454 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5439 "reflect.h2" +#line 5462 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5443 "reflect.h2" +#line 5466 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5447 "reflect.h2" +#line 5470 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8986,22 +9009,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5458 "reflect.h2" +#line 5481 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5464 "reflect.h2" +#line 5487 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5468 "reflect.h2" +#line 5491 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5472 "reflect.h2" +#line 5495 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9009,7 +9032,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5479 "reflect.h2" +#line 5502 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9021,10 +9044,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5492 "reflect.h2" +#line 5515 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5495 "reflect.h2" +#line 5518 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9064,7 +9087,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5535 "reflect.h2" +#line 5558 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9076,14 +9099,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5546 "reflect.h2" +#line 5569 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5547 "reflect.h2" +#line 5570 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5548 "reflect.h2" +#line 5571 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5550 "reflect.h2" +#line 5573 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9093,10 +9116,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5559 "reflect.h2" +#line 5582 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5561 "reflect.h2" +#line 5584 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9118,14 +9141,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5582 "reflect.h2" +#line 5605 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5583 "reflect.h2" +#line 5606 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5584 "reflect.h2" +#line 5607 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5586 "reflect.h2" +#line 5609 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9139,7 +9162,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5599 "reflect.h2" +#line 5622 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9161,7 +9184,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5620 "reflect.h2" +#line 5643 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9172,12 +9195,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5630 "reflect.h2" +#line 5653 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5631 "reflect.h2" +#line 5654 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5636 "reflect.h2" +#line 5659 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9232,7 +9255,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5690 "reflect.h2" +#line 5713 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9272,7 +9295,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5729 "reflect.h2" +#line 5752 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9288,21 +9311,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5746 "reflect.h2" +#line 5769 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5747 "reflect.h2" +#line 5770 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5748 "reflect.h2" +#line 5771 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5750 "reflect.h2" +#line 5773 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5765 "reflect.h2" +#line 5788 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9310,7 +9333,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5772 "reflect.h2" +#line 5795 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9320,22 +9343,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5790 "reflect.h2" +#line 5813 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5795 "reflect.h2" +#line 5818 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5801 "reflect.h2" +#line 5824 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5807 "reflect.h2" +#line 5830 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9344,7 +9367,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5815 "reflect.h2" +#line 5838 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9356,7 +9379,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5826 "reflect.h2" +#line 5849 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9364,7 +9387,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5833 "reflect.h2" +#line 5856 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9385,7 +9408,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5854 "reflect.h2" +#line 5877 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9395,7 +9418,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5864 "reflect.h2" +#line 5887 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9418,33 +9441,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5888 "reflect.h2" +#line 5911 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5894 "reflect.h2" +#line 5917 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5898 "reflect.h2" +#line 5921 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5904 "reflect.h2" +#line 5927 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5912 "reflect.h2" +#line 5935 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9453,7 +9476,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5920 "reflect.h2" +#line 5943 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9462,22 +9485,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5930 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5934 "reflect.h2" +#line 5957 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5938 "reflect.h2" +#line 5961 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5942 "reflect.h2" +#line 5965 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9501,18 +9524,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5967 "reflect.h2" +#line 5990 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5982 "reflect.h2" +#line 6005 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5984 "reflect.h2" +#line 6007 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9523,15 +9546,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5999 "reflect.h2" +#line 6022 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6002 "reflect.h2" +#line 6025 "reflect.h2" } -#line 6004 "reflect.h2" +#line 6027 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9549,7 +9572,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6021 "reflect.h2" +#line 6044 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9557,7 +9580,7 @@ generation_function_context::generation_function_context(){} } } -#line 6028 "reflect.h2" +#line 6051 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9571,7 +9594,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6041 "reflect.h2" +#line 6064 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9587,14 +9610,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6062 "reflect.h2" +#line 6085 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6064 "reflect.h2" +#line 6087 "reflect.h2" } -#line 6066 "reflect.h2" +#line 6089 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9603,11 +9626,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6081 "reflect.h2" +#line 6104 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6083 "reflect.h2" +#line 6106 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9615,7 +9638,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6090 "reflect.h2" +#line 6113 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9624,37 +9647,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6098 "reflect.h2" +#line 6121 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6112 "reflect.h2" +#line 6135 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6116 "reflect.h2" +#line 6139 "reflect.h2" } -#line 6118 "reflect.h2" +#line 6141 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6122 "reflect.h2" +#line 6145 "reflect.h2" } -#line 6124 "reflect.h2" +#line 6147 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6128 "reflect.h2" +#line 6151 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9663,14 +9686,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6134 "reflect.h2" +#line 6157 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6139 "reflect.h2" +#line 6162 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9683,7 +9706,7 @@ size_t i{0}; } } -#line 6151 "reflect.h2" +#line 6174 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9705,7 +9728,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6172 "reflect.h2" +#line 6195 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9724,7 +9747,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6190 "reflect.h2" +#line 6213 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9740,14 +9763,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6205 "reflect.h2" +#line 6228 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6211 "reflect.h2" +#line 6234 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9755,19 +9778,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6228 "reflect.h2" +#line 6251 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6229 "reflect.h2" +#line 6252 "reflect.h2" { -#line 6234 "reflect.h2" +#line 6257 "reflect.h2" } -#line 6237 "reflect.h2" +#line 6260 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9893,7 +9916,7 @@ size_t i{0}; ); } -#line 6362 "reflect.h2" +#line 6385 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9903,13 +9926,13 @@ size_t i{0}; ); } -#line 6371 "reflect.h2" +#line 6394 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6376 "reflect.h2" +#line 6399 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9920,12 +9943,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6388 "reflect.h2" +#line 6411 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6393 "reflect.h2" +#line 6416 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9959,7 +9982,7 @@ size_t i{0}; } -#line 6429 "reflect.h2" +#line 6452 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9968,19 +9991,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6452 "reflect.h2" +#line 6475 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6453 "reflect.h2" +#line 6476 "reflect.h2" { -#line 6458 "reflect.h2" +#line 6481 "reflect.h2" } -#line 6460 "reflect.h2" +#line 6483 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10082,19 +10105,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6561 "reflect.h2" +#line 6584 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6565 "reflect.h2" +#line 6588 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6589 "reflect.h2" +#line 6612 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10113,7 +10136,7 @@ size_t i{0}; return r; } -#line 6607 "reflect.h2" +#line 6630 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10128,7 +10151,7 @@ size_t i{0}; return r; } -#line 6621 "reflect.h2" +#line 6644 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10288,7 +10311,7 @@ size_t i{0}; } } -#line 6780 "reflect.h2" +#line 6803 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10297,7 +10320,7 @@ size_t i{0}; return r; } -#line 6788 "reflect.h2" +#line 6811 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10316,7 +10339,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6806 "reflect.h2" +#line 6829 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10348,7 +10371,7 @@ size_t i{0}; } } -#line 6837 "reflect.h2" +#line 6860 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10359,7 +10382,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6849 "reflect.h2" +#line 6872 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10398,7 +10421,7 @@ size_t i{0}; return r; } -#line 6890 "reflect.h2" +#line 6913 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10416,7 +10439,7 @@ size_t i{0}; }} } -#line 6910 "reflect.h2" +#line 6933 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10430,16 +10453,16 @@ size_t i{0}; } } -#line 6936 "reflect.h2" +#line 6959 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6939 "reflect.h2" +#line 6962 "reflect.h2" } -#line 6941 "reflect.h2" +#line 6964 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10451,7 +10474,7 @@ size_t i{0}; } } -#line 6952 "reflect.h2" +#line 6975 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10459,14 +10482,14 @@ size_t i{0}; return r; } -#line 6959 "reflect.h2" +#line 6982 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6967 "reflect.h2" +#line 6990 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10492,7 +10515,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6995 "reflect.h2" +#line 7018 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10518,11 +10541,11 @@ size_t i{0}; return r; } -#line 7032 "reflect.h2" +#line 7055 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7034 "reflect.h2" +#line 7057 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10596,7 +10619,7 @@ size_t i{0}; return nullptr; } -#line 7107 "reflect.h2" +#line 7130 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10609,7 +10632,7 @@ size_t i{0}; }} } -#line 7119 "reflect.h2" +#line 7142 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10623,7 +10646,7 @@ size_t i{0}; }} } -#line 7132 "reflect.h2" +#line 7155 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10643,7 +10666,7 @@ size_t i{0}; return r; } -#line 7151 "reflect.h2" +#line 7174 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10654,7 +10677,7 @@ size_t i{0}; return r; } -#line 7161 "reflect.h2" +#line 7184 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10666,14 +10689,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7172 "reflect.h2" +#line 7195 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7184 "reflect.h2" +#line 7207 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10697,7 +10720,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7208 "reflect.h2" +#line 7231 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10707,7 +10730,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7220 "reflect.h2" +#line 7243 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10723,7 +10746,7 @@ size_t i{0}; } } -#line 7240 "reflect.h2" +#line 7263 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10741,15 +10764,15 @@ size_t i{0}; }} } -#line 7276 "reflect.h2" +#line 7299 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7279 "reflect.h2" +#line 7302 "reflect.h2" } -#line 7281 "reflect.h2" +#line 7304 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10785,7 +10808,7 @@ size_t i{0}; return source; } -#line 7316 "reflect.h2" +#line 7339 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10801,7 +10824,7 @@ size_t i{0}; } } -#line 7332 "reflect.h2" +#line 7355 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10810,7 +10833,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10865,7 +10888,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7401 "reflect.h2" +#line 7424 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10987,7 +11010,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7523 "reflect.h2" +#line 7546 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index aed326da1..5a6746fcf 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3956,6 +3956,8 @@ autodiff_context: type = { "_od_.push_back(_ad1_);\n") ); + public suffix: std::string = "_d"; + gen_temporary : (inout this) -> std::string = { temporary_count += 1; return "temp_(temporary_count)$"; @@ -4020,7 +4022,7 @@ autodiff_expression_handler: type = { } gen_lhs_assignment: (inout this, prim: std::string, fwd: std::string, primal_first: bool = false) = { - lhs_d : std::string = lhs + "_d"; + lhs_d : std::string = lhs + ctx*.suffix; if lhs == "_" { // TODO: Maybe improve discard handling lhs_d = lhs; @@ -4117,7 +4119,7 @@ autodiff_expression_handler: type = { if 1 != terms.ssize() { object = primary.to_string(); - object_d = primary.to_string() + "_d"; + object_d = primary.to_string() + ctx*.suffix; } else { function_name = primary.to_string(); @@ -4168,15 +4170,15 @@ autodiff_expression_handler: type = { } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. - diff += "(function_name)$_diff("; + diff += "(function_name)$(ctx*.suffix)$("; for args do (arg) { - diff += "(arg)$, (arg)$_d,"; + diff += "(arg)$, (arg)$(ctx*.suffix)$,"; } diff += ");\n"; if has_return { // TODO: Look up return value name of function. - gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r_d", /* switch order = */ true); + gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r(ctx*.suffix)$", /* switch order = */ true); } // TODO: Add function to list of functions/objects for differentiation. @@ -4201,13 +4203,13 @@ autodiff_expression_handler: type = { if !ret.empty() { code = string_util::replace_all(code, "_r_", ret); - code = string_util::replace_all(code, "_rd_", ret + "_d"); + code = string_util::replace_all(code, "_rd_", ret + ctx*.suffix); } (copy i := 1) for args do (arg) { code = string_util::replace_all(code, "_a(i)$_", arg); - code = string_util::replace_all(code, "_ad(i)$_", arg + "_d"); + code = string_util::replace_all(code, "_ad(i)$_", arg + ctx*.suffix); } diff += code; @@ -4273,7 +4275,7 @@ autodiff_expression_handler: type = { } var := handle_expression_term(term.get_term()); - fwd += "(var)$_d"; + fwd += "(var)$(ctx*.suffix)$"; primal += "(var)$"; first = false; @@ -4297,11 +4299,11 @@ autodiff_expression_handler: type = { primal : std::string = ""; if "*" == op { - fwd = "(arg_a)$ * (arg_b)$_d + (arg_b)$ * (arg_a)$_d"; + fwd = "(arg_a)$ * (arg_b)$(ctx*.suffix)$ + (arg_b)$ * (arg_a)$(ctx*.suffix)$"; primal = "(arg_a)$ * (arg_b)$"; } else if "/" == op { - fwd = "(arg_a)$_d / (arg_b)$ - (arg_a)$ * (arg_b)$_d / ((arg_b)$ * (arg_b)$)"; + fwd = "(arg_a)$(ctx*.suffix)$ / (arg_b)$ - (arg_a)$ * (arg_b)$(ctx*.suffix)$ / ((arg_b)$ * (arg_b)$)"; primal = "(arg_a)$ / (arg_b)$"; } else { @@ -4317,7 +4319,7 @@ autodiff_expression_handler: type = { // Temporary t := ctx*.gen_temporary(); // TODO: Get type of expression, in order to define the type of t. - diff += "(t)$_d := (fwd)$;"; + diff += "(t)$(ctx*.suffix)$ := (fwd)$;"; diff += "(t)$ := (primal)$;"; arg_a = t; @@ -4364,7 +4366,7 @@ autodiff_expression_handler: type = { traverse: (override inout this, primary: meta::primary_expression) = { if primary.is_identifier() { - gen_lhs_assignment(primary.to_string(), primary.to_string() + "_d"); + gen_lhs_assignment(primary.to_string(), primary.to_string() + ctx*.suffix); } else if primary.is_expression_list() { if primary.as_expression_list().is_empty() { @@ -4426,7 +4428,7 @@ autodiff_stmt_handler: type = { append(ad); } else { - diff += "(lhs)$_d : (ad_type)$;\n"; + diff += "(lhs)$(ctx*.suffix)$ : (ad_type)$;\n"; diff += "(lhs)$ : (type)$;\n"; } } @@ -4503,7 +4505,7 @@ autodiff_stmt_handler: type = { param := stmt.get_for_parameter(); param_style := to_string_view(param.get_passing_style()); param_decl := param.get_declaration(); - diff += "(copy (param_decl.name())$_d_iter := (range)$_d.begin())\n"; + diff += "(copy (param_decl.name())$_d_iter := (range)$(ctx*.suffix)$.begin())\n"; diff += "for (range)$ next ("; if stmt.has_next() { // TODO: Assumption is here that nothing is in the next expression @@ -4511,7 +4513,7 @@ autodiff_stmt_handler: type = { } diff += "(param_decl.name())$_d_iter++"; diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; - diff += "((param_style)$ (param_decl.name())$_d: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; + diff += "((param_style)$ (param_decl.name())$(ctx*.suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; pre_traverse(stmt.get_for_body()); diff += "}\n"; } @@ -4652,20 +4654,40 @@ autodiff_stmt_handler: type = { autodiff: (inout t: meta::type_declaration) = { + + suffix_token : std::string_view == "suffix="; + + args := t.get_arguments(); + + suffix : std::string = "_d"; + for args do (arg_str) { + if arg_str.starts_with("\"") && arg_str.ends_with("\"") { + arg := arg_str.substr(1, arg_str.ssize() - 2); + + if arg.starts_with(suffix_token) { + suffix = arg.substr(suffix_token.size()); + continue; + } + } + + t.error("AD: Unknown argument: (arg_str)$"); + return; + } + for t.get_members() do (m) if m.is_function() { mf := m.as_function(); - diff: std::string = " (mf.name())$_diff: ("; + diff: std::string = " (mf.name())$(suffix)$: ("; // 1. Generate the modified signature // a) Parameters for mf.get_parameters() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$, "; - diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$, "; + diff += "(param.get_declaration().name())$(suffix)$ : (param.get_declaration().type())$, "; } diff += ") -> ("; @@ -4676,16 +4698,16 @@ autodiff: (inout t: meta::type_declaration) = // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if mf.has_deduced_return_type() { // TODO: Take care of initialization order error. - diff += "r, r_d, "; + diff += "r, r(suffix)$, "; } else { - diff += "r: (mf.get_unnamed_return_type())$ = (), r_d: (mf.get_unnamed_return_type())$ = (), "; + diff += "r: (mf.get_unnamed_return_type())$ = (), r(suffix)$: (mf.get_unnamed_return_type())$ = (), "; } } else { for mf.get_returns() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(param.get_declaration().name())$_d : (param.get_declaration().type())$ = 0.0, "; + diff += "(param.get_declaration().name())$(suffix)$ : (param.get_declaration().type())$ = 0.0, "; } } @@ -4699,6 +4721,7 @@ autodiff: (inout t: meta::type_declaration) = } ad_ctx: autodiff_context = (); + ad_ctx.suffix = suffix; ad_impl : autodiff_stmt_handler = (ad_ctx&, mf); From 065c3e9ab94baabed12f4f9823c040cc84df6e54 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 12 Aug 2025 15:16:34 +0200 Subject: [PATCH 20/54] Added second order test. --- regression-tests/pure2-autodiff.cpp2 | 8 ++ .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 77 ++++++++++++++++++- .../test-results/pure2-autodiff.cpp2.output | 59 ++++++++++++++ 4 files changed, 142 insertions(+), 3 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 907a08cca..8747212fd 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -153,6 +153,11 @@ ad_test: @autodiff @print type = { } } +ad_test_twice: @autodiff @autodiff<"suffix=_d2"> @print type = { + mul_1: (x: double) -> (r: double) = { + r = x * x; + } +} write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double, ret) = { std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$) = (r = (ret.r)$, r_d = (ret.r_d)$)" << std::endl; @@ -190,4 +195,7 @@ main: () = { write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); + + r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); + std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 387d130b1..f9c2c2a00 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -23,3 +23,4 @@ diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 94839f3e6..003dcab59 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -11,6 +11,9 @@ #line 2 "pure2-autodiff.cpp2" class ad_test; +#line 156 "pure2-autodiff.cpp2" +class ad_test_twice; + //=== Cpp2 type definitions and function declarations =========================== @@ -259,10 +262,35 @@ public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::imp #line 154 "pure2-autodiff.cpp2" }; +class ad_test_twice { +using mul_1_ret = double; + #line 157 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; +struct mul_1_d_ret { double r; double r_d; }; + + + public: [[nodiscard]] static auto mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d) -> mul_1_d_ret; + +struct mul_1_d2_ret { double r; double r_d2; }; + +public: [[nodiscard]] static auto mul_1_d2(cpp2::impl::in x, cpp2::impl::in x_d2) -> mul_1_d2_ret; + +struct mul_1_d_d2_ret { double r; double r_d2; double r_d; double r_d_d2; }; + +public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::impl::in x_d2, cpp2::impl::in x_d, cpp2::impl::in x_d_d2) -> mul_1_d_d2_ret; + + public: ad_test_twice() = default; + public: ad_test_twice(ad_test_twice const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(ad_test_twice const&) -> void = delete; + + +#line 160 "pure2-autodiff.cpp2" +}; + auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 161 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -788,11 +816,51 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; } #line 157 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ + cpp2::impl::deferred_init r; +#line 158 "pure2-autodiff.cpp2" + r.construct(x * x); + return std::move(r.value()); } + + [[nodiscard]] auto ad_test_twice::mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d) -> mul_1_d_ret{ + double r {0.0}; + double r_d {0.0};r_d = x * x_d + x * x_d; + r = x * x; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test_twice::mul_1_d2(cpp2::impl::in x, cpp2::impl::in x_d2) -> mul_1_d2_ret{ + double r {0.0}; + double r_d2 {0.0};r_d2 = x * x_d2 + x * x_d2; + r = x * x; + return { std::move(r), std::move(r_d2) }; + } + + [[nodiscard]] auto ad_test_twice::mul_1_d_d2(cpp2::impl::in x, cpp2::impl::in x_d2, cpp2::impl::in x_d, cpp2::impl::in x_d_d2) -> mul_1_d_d2_ret{ + double r {0.0}; + double r_d2 {0.0}; + double r_d {0.0}; + double r_d_d2 {0.0}; +auto temp_1_d2 {x * x_d_d2 + x_d * x_d2}; + + auto temp_1 {x * x_d}; + + auto temp_2_d2 {x * x_d_d2 + x_d * x_d2}; + + auto temp_2 {x * x_d}; + r_d_d2 = cpp2::move(temp_1_d2) + cpp2::move(temp_2_d2); + r_d = cpp2::move(temp_1) + cpp2::move(temp_2); + r_d2 = x * x_d2 + x * x_d2; + r = x * x; + return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; + } + +#line 162 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 161 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -824,6 +892,9 @@ auto main() -> int{ write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); + + auto r_twice {ad_test_twice::mul_1_d_d2(x, x_d, cpp2::move(x_d), 0.0)}; + std::cout << "2nd order diff of x*x at " + cpp2::to_string(cpp2::move(x)) + " = " + cpp2::to_string(cpp2::move(r_twice).r_d_d2) + "" << std::endl; } diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 6d8d50fbe..d6cf2b99b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -755,5 +755,64 @@ ad_test:/* @autodiff @print */ type = return; } } + + +ad_test_twice:/* @autodiff @autodiff<"suffix=_d2"> @print */ type = +{ + mul_1:(in x: double, ) -> (out r: double, ) = + { + r = x * x; + return; + } + + mul_1_d:( + in x: double, + in x_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + r_d = x * x_d + x * x_d; + r = x * x; + return; + } + + mul_1_d2:( + in x: double, + in x_d2: double, + ) -> ( + out r: double = 0.0, + out r_d2: double = 0.0, + ) = + { + r_d2 = x * x_d2 + x * x_d2; + r = x * x; + return; + } + + mul_1_d_d2:( + in x: double, + in x_d2: double, + in x_d: double, + in x_d_d2: double, + ) -> ( + out r: double = 0.0, + out r_d2: double = 0.0, + out r_d: double = 0.0, + out r_d_d2: double = 0.0, + ) = + { + temp_1_d2: _ = x * x_d_d2 + x_d * x_d2; + temp_1: _ = x * x_d; + temp_2_d2: _ = x * x_d_d2 + x_d * x_d2; + temp_2: _ = x * x_d; + r_d_d2 = temp_1_d2 + temp_2_d2; + r_d = temp_1 + temp_2; + r_d2 = x * x_d2 + x * x_d2; + r = x * x; + return; + } +} ok (all Cpp2, passes safety checks) From 93e676f20b1db52cfd891b99308e7ddfa104ea6a Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 07:57:26 +0200 Subject: [PATCH 21/54] Remove initialization order workaround. --- regression-tests/pure2-autodiff.cpp2 | 1 - .../test-results/pure2-autodiff.cpp | 45 +++++++++---------- .../test-results/pure2-autodiff.cpp2.output | 3 -- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 8747212fd..db1c354fa 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -111,7 +111,6 @@ ad_test: @autodiff @print type = { } intermediate_no_init: (x: double, y: double) -> (r: double) = { - r = 0.0; // TODO: r has to be initialized before t (create issue or wait for fix) t: double; t = x + y; diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 003dcab59..0ae197411 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -11,7 +11,7 @@ #line 2 "pure2-autodiff.cpp2" class ad_test; -#line 156 "pure2-autodiff.cpp2" +#line 155 "pure2-autodiff.cpp2" class ad_test_twice; @@ -137,17 +137,17 @@ using intermediate_no_init_ret = double; using while_loop_ret = double; -#line 121 "pure2-autodiff.cpp2" +#line 120 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 130 "pure2-autodiff.cpp2" +#line 129 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 141 "pure2-autodiff.cpp2" +#line 140 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_d_ret { double r; double r_d; }; @@ -259,13 +259,13 @@ public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test const&) -> void = delete; -#line 154 "pure2-autodiff.cpp2" +#line 153 "pure2-autodiff.cpp2" }; class ad_test_twice { using mul_1_ret = double; -#line 157 "pure2-autodiff.cpp2" +#line 156 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -285,12 +285,12 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 160 "pure2-autodiff.cpp2" +#line 159 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 166 "pure2-autodiff.cpp2" +#line 165 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -474,17 +474,16 @@ auto main() -> int; [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; #line 114 "pure2-autodiff.cpp2" - r.construct(0.0);// TODO: r has to be initialized before t (create issue or wait for fix) cpp2::impl::deferred_init t; t.construct(x + y); - r.value() = cpp2::move(t.value()); + r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 121 "pure2-autodiff.cpp2" +#line 120 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 122 "pure2-autodiff.cpp2" +#line 121 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -493,10 +492,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 130 "pure2-autodiff.cpp2" +#line 129 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 131 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -507,10 +506,10 @@ auto main() -> int; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 141 "pure2-autodiff.cpp2" +#line 140 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 142 "pure2-autodiff.cpp2" +#line 141 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -739,10 +738,8 @@ double t_d {}; [[nodiscard]] auto ad_test::intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_d_ret{ double r {0.0}; - double r_d {0.0};r_d = { }; - r = 0.0; - - cpp2::impl::deferred_init t_d; + double r_d {0.0}; +cpp2::impl::deferred_init t_d; cpp2::impl::deferred_init t; t_d.construct(x_d + y_d); @@ -815,10 +812,10 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 157 "pure2-autodiff.cpp2" +#line 156 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 158 "pure2-autodiff.cpp2" +#line 157 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -855,12 +852,12 @@ auto temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 162 "pure2-autodiff.cpp2" +#line 161 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 166 "pure2-autodiff.cpp2" +#line 165 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index d6cf2b99b..831fdd03b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -223,7 +223,6 @@ ad_test:/* @autodiff @print */ type = in y: double, ) -> (out r: double, ) = { - r = 0.0; t: double; t = x + y; r = t; @@ -665,8 +664,6 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - r_d = (); - r = 0.0; t_d: double; t: double; t_d = x_d + y_d; From 86f0c7b0813c03392c2535c0f0e9627fa03058d5 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 11:08:27 +0200 Subject: [PATCH 22/54] Taylor polynomial propagation implementation. --- include/cpp2taylor.h | 389 ++++++++++++++++++ include/cpp2taylor.h2 | 194 +++++++++ regression-tests/mixed-autodiff-taylor.cpp2 | 85 ++++ .../mixed-autodiff-taylor.cpp.execution | 63 +++ .../test-results/mixed-autodiff-taylor.cpp | 213 ++++++++++ .../mixed-autodiff-taylor.cpp2.output | 2 + 6 files changed, 946 insertions(+) create mode 100644 include/cpp2taylor.h create mode 100644 include/cpp2taylor.h2 create mode 100644 regression-tests/mixed-autodiff-taylor.cpp2 create mode 100644 regression-tests/test-results/gcc-13-c++2b/mixed-autodiff-taylor.cpp.execution create mode 100644 regression-tests/test-results/mixed-autodiff-taylor.cpp create mode 100644 regression-tests/test-results/mixed-autodiff-taylor.cpp2.output diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h new file mode 100644 index 000000000..0308ab55e --- /dev/null +++ b/include/cpp2taylor.h @@ -0,0 +1,389 @@ + +#ifndef CPP2TAYLOR_H_CPP2 +#define CPP2TAYLOR_H_CPP2 + + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "cpp2taylor.h2" + +#line 4 "cpp2taylor.h2" +namespace cpp2 { + +template class taylor; + + +#line 192 "cpp2taylor.h2" +} + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "cpp2taylor.h2" +#ifndef CPP2_CPP2TAYLOR_H +#define CPP2_CPP2TAYLOR_H + +#line 4 "cpp2taylor.h2" +namespace cpp2 { + +template class taylor { + private: std::array v {}; + + public: explicit taylor(); + public: taylor(R const& d1); +#line 10 "cpp2taylor.h2" + public: auto operator=(R const& d1) -> taylor& ; + +#line 13 "cpp2taylor.h2" + public: taylor(taylor const& that); +#line 13 "cpp2taylor.h2" + public: auto operator=(taylor const& that) -> taylor& ; +#line 13 "cpp2taylor.h2" + public: taylor(taylor&& that) noexcept; +#line 13 "cpp2taylor.h2" + public: auto operator=(taylor&& that) noexcept -> taylor& ; + + // C++ interface + + public: [[nodiscard]] auto operator[](cpp2::impl::in k) const& -> R; + +#line 27 "cpp2taylor.h2" + public: [[nodiscard]] auto operator[](cpp2::impl::in i) & -> auto&&; + +#line 32 "cpp2taylor.h2" + // C++2 interface / AD interface + + public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; + +#line 44 "cpp2taylor.h2" + public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; + +#line 55 "cpp2taylor.h2" + public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; + +#line 66 "cpp2taylor.h2" + public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; + +#line 79 "cpp2taylor.h2" + public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; + +#line 97 "cpp2taylor.h2" + public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; + +#line 116 "cpp2taylor.h2" + public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; + +#line 135 "cpp2taylor.h2" + public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; + +#line 154 "cpp2taylor.h2" + public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; + +#line 171 "cpp2taylor.h2" + public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; + +#line 181 "cpp2taylor.h2" + public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; + +#line 190 "cpp2taylor.h2" +}; + +} // cpp2 namespace + +#endif // CPP2_CPP2TAYLOR_H + + +//=== Cpp2 function definitions ================================================= + +#line 1 "cpp2taylor.h2" + +#line 4 "cpp2taylor.h2" +namespace cpp2 { + +#line 9 "cpp2taylor.h2" + template taylor::taylor(){} +#line 10 "cpp2taylor.h2" + template taylor::taylor(R const& d1) + : v{ d1 }{ + +#line 12 "cpp2taylor.h2" + } +#line 10 "cpp2taylor.h2" + template auto taylor::operator=(R const& d1) -> taylor& { + v = d1; + return *this; + +#line 12 "cpp2taylor.h2" + } +#line 13 "cpp2taylor.h2" + template taylor::taylor(taylor const& that) + : v{ that.v }{} +#line 13 "cpp2taylor.h2" + template auto taylor::operator=(taylor const& that) -> taylor& { + v = that.v; + return *this; } +#line 13 "cpp2taylor.h2" + template taylor::taylor(taylor&& that) noexcept + : v{ std::move(that).v }{} +#line 13 "cpp2taylor.h2" + template auto taylor::operator=(taylor&& that) noexcept -> taylor& { + v = std::move(that).v; + return *this; } + +#line 17 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator[](cpp2::impl::in k) const& -> R{ + if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } + R r {CPP2_ASSERT_IN_BOUNDS(v, k - 1)}; +{ +auto i{2}; + +#line 21 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { + r *= i; + } +} +#line 24 "cpp2taylor.h2" + return r; + } + +#line 27 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator[](cpp2::impl::in i) & -> auto&&{ + if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = 1, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } + return CPP2_ASSERT_IN_BOUNDS(v, i - 1); + } + +#line 34 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ + if (cpp2::cpp2_default.is_active() && !([_0 = 0, _1 = i, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } + + if (i == 0) { + return v0; + } + + return CPP2_ASSERT_IN_BOUNDS(v, i - 1); + } + +#line 44 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ + taylor r {}; +{ +auto k{1}; + +#line 48 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); + } +} + +#line 52 "cpp2taylor.h2" + return r; + } + +#line 55 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ + taylor r {}; +{ +auto k{1}; + +#line 59 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); + } +} + +#line 63 "cpp2taylor.h2" + return r; + } + +#line 66 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ + taylor r {}; +{ +auto k{1}; + +#line 70 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { +{ +auto j{0}; + +#line 72 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); + } +} +#line 75 "cpp2taylor.h2" + } +} +#line 76 "cpp2taylor.h2" + return r; + } + +#line 79 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ + taylor r {}; + R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; + + R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),o0)}; +{ +auto k{1}; + +#line 86 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); +{ +auto j{0}; + +#line 89 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); + } +} +#line 92 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; + } +} +#line 94 "cpp2taylor.h2" + return r; + } + +#line 97 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ + taylor r {}; + R r0 {std::sqrt(v0)}; + + R factor {0.5 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(0.5),r0)}; +{ +auto k{1}; + +#line 104 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); +{ +auto j{1}; + +#line 107 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); + } +} +#line 110 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; + } +} + +#line 113 "cpp2taylor.h2" + return r; + } + +#line 116 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ + taylor r {}; + R r0 {std::log(v0)}; + + R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),v0)}; +{ +auto k{1}; + +#line 123 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); +{ +auto j{1}; + +#line 126 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); + } +} +#line 129 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); + } +} + +#line 132 "cpp2taylor.h2" + return r; + } + +#line 135 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ + taylor r {}; + R r0 {std::exp(v0)}; + + R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),v0)}; +{ +auto k{1}; + +#line 142 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { +{ +auto j{1}; + +#line 144 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); + } +} +#line 147 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); + } +} + +#line 150 "cpp2taylor.h2" + return r; + } + +#line 154 "cpp2taylor.h2" + template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ + R s0 {std::sin(u0)}; + R c0 {std::cos(u0)}; +{ +auto k{1}; + +#line 159 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { +{ +auto j{1}; + +#line 161 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { + CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); + CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); + } +} +#line 165 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); + CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); + } +} +#line 168 "cpp2taylor.h2" + } + +#line 171 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ + taylor t {}; + taylor r {}; + + comp_sin_cos(r, t, (*this), v0); + static_cast(cpp2::move(t)); + + return r; + } + +#line 181 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ + taylor t {}; + taylor r {}; + + comp_sin_cos(t, r, (*this), v0); + static_cast(cpp2::move(t)); + + return r; + } + +#line 192 "cpp2taylor.h2" +} + +#endif diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 new file mode 100644 index 000000000..56afac7f5 --- /dev/null +++ b/include/cpp2taylor.h2 @@ -0,0 +1,194 @@ +#ifndef CPP2_CPP2TAYLOR_H +#define CPP2_CPP2TAYLOR_H + +cpp2: namespace = { + +taylor: type = { + v : std::array = (); + + operator=:(out this) = {} + operator=:(out this, d1: R) = { + v[0] = d1; + } + operator=:(out this, that) = {} + + // C++ interface + + operator[]: (this, k: int) -> R = { + assert(1 <= k <= dim); + r: R = v[k - 1]; + (copy i := 2) + while i <= k next i += 1 { + r *= i; + } + return r; + } + + operator[]: (inout this, i: int) -> forward_ref _ = { + assert(1 <= 1 <= dim); + return v[i - 1]; + } + + // C++2 interface / AD interface + + get: (this, i: int, v0: R) -> R = { + assert(0 <= i <= dim); + + if i == 0 { + return v0; + } + + return v[i - 1]; + } + + add: (this, o: taylor, v0: R, o0: R) -> taylor = { + r: taylor = (); + + (copy k:= 1) + while k <= dim next k += 1 { + r.v[k - 1] = get(k, v0) + o.get(k, o0); + } + + return r; + } + + sub: (this, o: taylor, v0: R, o0: R) -> taylor = { + r: taylor = (); + + (copy k:= 1) + while k <= dim next k += 1 { + r.v[k - 1] = get(k, v0) - o.get(k, o0); + } + + return r; + } + + mul: (this, o: taylor, v0: R, o0: R) -> taylor = { + r: taylor = (); + + (copy k:= 1) + while k <= dim next k += 1 { + (copy j := 0) + while j <= k next j += 1 { + r..v[k - 1] += get(j, v0) * o..get(k - j, o0); + } + } + return r; + } + + div: (this, o: taylor, v0: R, o0: R) -> taylor = { + r: taylor = (); + r0: R = v0 / o0; + + factor : R = 1.0 / o0; + + (copy k:= 1) + while k <= dim next k += 1 { + r..v[k - 1] = get(k, v0); + (copy j := 0) + while j < k next j += 1 { + r..v[k - 1] -= r.get(j, r0) * o..get(k - j, o0); + } + r..v[k - 1] *= factor; + } + return r; + } + + sqrt: (this, v0: R) -> taylor = { + r: taylor = (); + r0: R = std::sqrt(v0); + + factor : R = 0.5 / r0; + + (copy k:= 1) + while k <= dim next k += 1 { + r..v[k - 1] = get(k, v0); + (copy j := 1) + while j < k next j += 1 { + r..v[k - 1] -= r..get(j, r0) * r..get(k - j, r0); + } + r..v[k - 1] *= factor; + } + + return r; + } + + log: (this, v0: R) -> taylor = { + r: taylor = (); + r0: R = std::log(v0); + + factor : R = 1.0 / v0; + + (copy k:= 1) + while k <= dim next k += 1 { + r..v[k - 1] =k * get(k, v0); + (copy j := 1) + while j < k next j += 1 { + r..v[k - 1] -= j * get(k - j, v0) * r..get(j, r0); + } + r..v[k - 1] *= factor / k; + } + + return r; + } + + exp: (this, v0: R) -> taylor = { + r: taylor = (); + r0: R = std::exp(v0); + + factor : R = 1.0 / v0; + + (copy k:= 1) + while k <= dim next k += 1 { + (copy j := 1) + while j <= k next j += 1 { + r..v[k - 1] += j * r..get(k - j, r0) * get(j, v0); + } + r..v[k - 1] /= k; + } + + return r; + } + + + comp_sin_cos: (inout s: taylor, inout c: taylor, u: taylor, u0: R) = { + s0: R = std::sin(u0); + c0: R = std::cos(u0); + + (copy k:= 1) + while k <= dim next k += 1 { + (copy j := 1) + while j <= k next j += 1 { + s..v[k - 1] += j * u..get(j, u0) * c.get(k - j, c0); + c..v[k - 1] -= j * u..get(j, u0) * s.get(k - j, s0); + } + s..v[k - 1] /= k; + c..v[k - 1] /= k; + } + } + + + sin: (this, v0: R) -> taylor = { + t: taylor = (); + r: taylor = (); + + comp_sin_cos(r, t, this, v0); + _ = t; + + return r; + } + + cos: (this, v0: R) -> taylor = { + t: taylor = (); + r: taylor = (); + + comp_sin_cos(t, r, this, v0); + _ = t; + + return r; + } +} + +} // cpp2 namespace + +#endif // CPP2_CPP2TAYLOR_H \ No newline at end of file diff --git a/regression-tests/mixed-autodiff-taylor.cpp2 b/regression-tests/mixed-autodiff-taylor.cpp2 new file mode 100644 index 000000000..d7d4ff43c --- /dev/null +++ b/regression-tests/mixed-autodiff-taylor.cpp2 @@ -0,0 +1,85 @@ +#include + +order : int == 6; +taylor: type == cpp2::taylor; + +test_add: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y = x.add(x, x0, x0); + y0 = x0 + x0; +} + +test_sub: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = 0.0; + y = taylor(); + + y = y.sub(x, y0, x0); + y0 = y0 - x0; +} + +test_mul: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = x0; + y = x; + + (copy i:=0) + while i < 6 next i += 1 { + y = y..mul(x, y0, x0); + y0 *= x0; + } +} + +test_div: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = 1.0; + y = taylor(); + + y = y.div(x, y0, x0); + y0 /= x0; +} + +test_sqrt: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = sqrt(x0); + y = x.sqrt(x0); +} + +test_log: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = log(x0); + y = x.log(x0); +} + +test_exp: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = exp(x0); + y = x.exp(x0); +} + +test_sin: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = sin(x0); + y = x.sin(x0); +} + +test_cos: (x0: double, x: taylor) -> (y0: double, y: taylor) = { + y0 = cos(x0); + y = x.cos(x0); +} + +write_output: (func: std::string, x: double, x_d: taylor, ret) = { + std::cout << "(func)$ = (ret.y0)$" << std::endl; + (copy i:=1) + while i <= order next i += 1 { + std::cout << "(func)$ diff order (i)$ = (ret.y[i])$" << std::endl; + } +} + +main: () = { + + x: double = 2.0; + x_d: taylor = (1.0); + + write_output("x + x", x, x_d, test_add(x, x_d)); + write_output("0 - x", x, x_d, test_sub(x, x_d)); + write_output("x^7", x, x_d, test_mul(x, x_d)); + write_output("1/x", x, x_d, test_div(x, x_d)); + write_output("sqrt(x)", x, x_d, test_sqrt(x, x_d)); + write_output("log(x)", x, x_d, test_log(x, x_d)); + write_output("exp(x)", x, x_d, test_exp(x, x_d)); + write_output("sin(x)", x, x_d, test_sin(x, x_d)); + write_output("cos(x)", x, x_d, test_cos(x, x_d)); +} diff --git a/regression-tests/test-results/gcc-13-c++2b/mixed-autodiff-taylor.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/mixed-autodiff-taylor.cpp.execution new file mode 100644 index 000000000..0a486b06f --- /dev/null +++ b/regression-tests/test-results/gcc-13-c++2b/mixed-autodiff-taylor.cpp.execution @@ -0,0 +1,63 @@ +x + x = 4.000000 +x + x diff order 1 = 2.000000 +x + x diff order 2 = 0.000000 +x + x diff order 3 = 0.000000 +x + x diff order 4 = 0.000000 +x + x diff order 5 = 0.000000 +x + x diff order 6 = 0.000000 +0 - x = -2.000000 +0 - x diff order 1 = -1.000000 +0 - x diff order 2 = 0.000000 +0 - x diff order 3 = 0.000000 +0 - x diff order 4 = 0.000000 +0 - x diff order 5 = 0.000000 +0 - x diff order 6 = 0.000000 +x^7 = 128.000000 +x^7 diff order 1 = 448.000000 +x^7 diff order 2 = 1344.000000 +x^7 diff order 3 = 3360.000000 +x^7 diff order 4 = 6720.000000 +x^7 diff order 5 = 10080.000000 +x^7 diff order 6 = 10080.000000 +1/x = 0.500000 +1/x diff order 1 = -0.250000 +1/x diff order 2 = 0.250000 +1/x diff order 3 = -0.375000 +1/x diff order 4 = 0.750000 +1/x diff order 5 = -1.875000 +1/x diff order 6 = 5.625000 +sqrt(x) = 1.414214 +sqrt(x) diff order 1 = 0.353553 +sqrt(x) diff order 2 = -0.088388 +sqrt(x) diff order 3 = 0.066291 +sqrt(x) diff order 4 = -0.082864 +sqrt(x) diff order 5 = 0.145012 +sqrt(x) diff order 6 = -0.326277 +log(x) = 0.693147 +log(x) diff order 1 = 0.500000 +log(x) diff order 2 = -0.250000 +log(x) diff order 3 = 0.250000 +log(x) diff order 4 = -0.375000 +log(x) diff order 5 = 0.750000 +log(x) diff order 6 = -1.875000 +exp(x) = 7.389056 +exp(x) diff order 1 = 7.389056 +exp(x) diff order 2 = 7.389056 +exp(x) diff order 3 = 7.389056 +exp(x) diff order 4 = 7.389056 +exp(x) diff order 5 = 7.389056 +exp(x) diff order 6 = 7.389056 +sin(x) = 0.909297 +sin(x) diff order 1 = -0.416147 +sin(x) diff order 2 = -0.909297 +sin(x) diff order 3 = 0.416147 +sin(x) diff order 4 = 0.909297 +sin(x) diff order 5 = -0.416147 +sin(x) diff order 6 = -0.909297 +cos(x) = -0.416147 +cos(x) diff order 1 = -0.909297 +cos(x) diff order 2 = 0.416147 +cos(x) diff order 3 = 0.909297 +cos(x) diff order 4 = -0.416147 +cos(x) diff order 5 = -0.909297 +cos(x) diff order 6 = 0.416147 diff --git a/regression-tests/test-results/mixed-autodiff-taylor.cpp b/regression-tests/test-results/mixed-autodiff-taylor.cpp new file mode 100644 index 000000000..56a0606d4 --- /dev/null +++ b/regression-tests/test-results/mixed-autodiff-taylor.cpp @@ -0,0 +1,213 @@ +#include + + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "mixed-autodiff-taylor.cpp2" + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "mixed-autodiff-taylor.cpp2" + +#line 3 "mixed-autodiff-taylor.cpp2" +int inline constexpr order{ 6 }; +using taylor = cpp2::taylor; + +struct test_add_ret { double y0; taylor y; }; + +#line 6 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_add(cpp2::impl::in x0, cpp2::impl::in x) -> test_add_ret; +struct test_sub_ret { double y0; taylor y; }; + + + +#line 11 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sub(cpp2::impl::in x0, cpp2::impl::in x) -> test_sub_ret; +struct test_mul_ret { double y0; taylor y; }; + + + +#line 19 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_mul(cpp2::impl::in x0, cpp2::impl::in x) -> test_mul_ret; +struct test_div_ret { double y0; taylor y; }; + + + +#line 30 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_div(cpp2::impl::in x0, cpp2::impl::in x) -> test_div_ret; +struct test_sqrt_ret { double y0; taylor y; }; + + + +#line 38 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sqrt(cpp2::impl::in x0, cpp2::impl::in x) -> test_sqrt_ret; +struct test_log_ret { double y0; taylor y; }; + + + +#line 43 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_log(cpp2::impl::in x0, cpp2::impl::in x) -> test_log_ret; +struct test_exp_ret { double y0; taylor y; }; + + + +#line 48 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_exp(cpp2::impl::in x0, cpp2::impl::in x) -> test_exp_ret; +struct test_sin_ret { double y0; taylor y; }; + + + +#line 53 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sin(cpp2::impl::in x0, cpp2::impl::in x) -> test_sin_ret; +struct test_cos_ret { double y0; taylor y; }; + + + +#line 58 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_cos(cpp2::impl::in x0, cpp2::impl::in x) -> test_cos_ret; + +#line 63 "mixed-autodiff-taylor.cpp2" +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, auto const& ret) -> void; + +#line 71 "mixed-autodiff-taylor.cpp2" +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "mixed-autodiff-taylor.cpp2" + +#line 6 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_add(cpp2::impl::in x0, cpp2::impl::in x) -> test_add_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 7 "mixed-autodiff-taylor.cpp2" + y.construct(CPP2_UFCS(add)(x, x, x0, x0)); + y0.construct(x0 + x0); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 11 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sub(cpp2::impl::in x0, cpp2::impl::in x) -> test_sub_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 12 "mixed-autodiff-taylor.cpp2" + y0.construct(0.0); + y.construct(taylor()); + + y.value() = CPP2_UFCS(sub)(y.value(), x, y0.value(), x0); + y0.value() = y0.value() - x0; +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 19 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_mul(cpp2::impl::in x0, cpp2::impl::in x) -> test_mul_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 20 "mixed-autodiff-taylor.cpp2" + y0.construct(x0); + y.construct(x); +{ +auto i{0}; + +#line 24 "mixed-autodiff-taylor.cpp2" + for( ; cpp2::impl::cmp_less(i,6); i += 1 ) { + y.value() = y.value().mul(x, y0.value(), x0); + y0.value() *= x0; + } +} +#line 25 "mixed-autodiff-taylor.cpp2" + return { std::move(y0.value()), std::move(y.value()) }; + +#line 28 "mixed-autodiff-taylor.cpp2" +} + +#line 30 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_div(cpp2::impl::in x0, cpp2::impl::in x) -> test_div_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 31 "mixed-autodiff-taylor.cpp2" + y0.construct(1.0); + y.construct(taylor()); + + y.value() = CPP2_UFCS(div)(y.value(), x, y0.value(), x0); + y0.value() /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y0.value()),x0); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 38 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sqrt(cpp2::impl::in x0, cpp2::impl::in x) -> test_sqrt_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 39 "mixed-autodiff-taylor.cpp2" + y0.construct(sqrt(x0)); + y.construct(CPP2_UFCS(sqrt)(x, x0)); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 43 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_log(cpp2::impl::in x0, cpp2::impl::in x) -> test_log_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 44 "mixed-autodiff-taylor.cpp2" + y0.construct(log(x0)); + y.construct(CPP2_UFCS(log)(x, x0)); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 48 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_exp(cpp2::impl::in x0, cpp2::impl::in x) -> test_exp_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 49 "mixed-autodiff-taylor.cpp2" + y0.construct(exp(x0)); + y.construct(CPP2_UFCS(exp)(x, x0)); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 53 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_sin(cpp2::impl::in x0, cpp2::impl::in x) -> test_sin_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 54 "mixed-autodiff-taylor.cpp2" + y0.construct(sin(x0)); + y.construct(CPP2_UFCS(sin)(x, x0)); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 58 "mixed-autodiff-taylor.cpp2" +[[nodiscard]] auto test_cos(cpp2::impl::in x0, cpp2::impl::in x) -> test_cos_ret{ + cpp2::impl::deferred_init y0; + cpp2::impl::deferred_init y; +#line 59 "mixed-autodiff-taylor.cpp2" + y0.construct(cos(x0)); + y.construct(CPP2_UFCS(cos)(x, x0)); +return { std::move(y0.value()), std::move(y.value()) }; } + +#line 63 "mixed-autodiff-taylor.cpp2" +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, auto const& ret) -> void{ + std::cout << "" + cpp2::to_string(func) + " = " + cpp2::to_string(ret.y0) + "" << std::endl; +{ +auto i{1}; + +#line 66 "mixed-autodiff-taylor.cpp2" + for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { + std::cout << "" + cpp2::to_string(func) + " diff order " + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.y, i)) + "" << std::endl; + } +} +#line 69 "mixed-autodiff-taylor.cpp2" +} + +#line 71 "mixed-autodiff-taylor.cpp2" +auto main() -> int{ + + double x {2.0}; + taylor x_d {1.0}; + + write_output("x + x", x, x_d, test_add(x, x_d)); + write_output("0 - x", x, x_d, test_sub(x, x_d)); + write_output("x^7", x, x_d, test_mul(x, x_d)); + write_output("1/x", x, x_d, test_div(x, x_d)); + write_output("sqrt(x)", x, x_d, test_sqrt(x, x_d)); + write_output("log(x)", x, x_d, test_log(x, x_d)); + write_output("exp(x)", x, x_d, test_exp(x, x_d)); + write_output("sin(x)", x, x_d, test_sin(x, x_d)); + write_output("cos(x)", x, x_d, test_cos(cpp2::move(x), cpp2::move(x_d))); +} + diff --git a/regression-tests/test-results/mixed-autodiff-taylor.cpp2.output b/regression-tests/test-results/mixed-autodiff-taylor.cpp2.output new file mode 100644 index 000000000..20bd4dd08 --- /dev/null +++ b/regression-tests/test-results/mixed-autodiff-taylor.cpp2.output @@ -0,0 +1,2 @@ +mixed-autodiff-taylor.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks) + From 617a0899243866fc1d7b45f83a336a1ad02d8588 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 12:17:20 +0200 Subject: [PATCH 23/54] Basic handling of higher order derivatives and handling of add and minus. --- include/cpp2taylor.h | 160 ++- include/cpp2taylor.h2 | 32 +- .../pure2-autodiff-higher-order.cpp2 | 70 ++ .../pure2-autodiff-higher-order.cpp.execution | 40 + .../pure2-autodiff-higher-order.cpp | 208 ++++ .../pure2-autodiff-higher-order.cpp2.output | 126 ++ source/reflect.h | 1109 +++++++++-------- source/reflect.h2 | 56 +- 8 files changed, 1210 insertions(+), 591 deletions(-) create mode 100644 regression-tests/pure2-autodiff-higher-order.cpp2 create mode 100644 regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution create mode 100644 regression-tests/test-results/pure2-autodiff-higher-order.cpp create mode 100644 regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index 0308ab55e..2fbdcc0ee 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -16,7 +16,7 @@ namespace cpp2 { template class taylor; -#line 192 "cpp2taylor.h2" +#line 218 "cpp2taylor.h2" } @@ -51,46 +51,57 @@ template class taylor { public: [[nodiscard]] auto operator[](cpp2::impl::in k) const& -> R; #line 27 "cpp2taylor.h2" - public: [[nodiscard]] auto operator[](cpp2::impl::in i) & -> auto&&; + public: auto set(cpp2::impl::in k, cpp2::impl::in value) & -> void; -#line 32 "cpp2taylor.h2" +#line 37 "cpp2taylor.h2" // C++2 interface / AD interface public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; -#line 44 "cpp2taylor.h2" +#line 49 "cpp2taylor.h2" + // Overload for simple handling of connected adds. + public: [[nodiscard]] auto operator+(cpp2::impl::in o) const& -> taylor; + +#line 54 "cpp2taylor.h2" + // Overload for simple handling of connected minuses. + public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; + +#line 59 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 55 "cpp2taylor.h2" +#line 70 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 66 "cpp2taylor.h2" +#line 81 "cpp2taylor.h2" public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 79 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 97 "cpp2taylor.h2" +#line 112 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; -#line 116 "cpp2taylor.h2" +#line 131 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; -#line 135 "cpp2taylor.h2" +#line 150 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; -#line 154 "cpp2taylor.h2" +#line 169 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; -#line 171 "cpp2taylor.h2" +#line 186 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; -#line 181 "cpp2taylor.h2" +#line 196 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; -#line 190 "cpp2taylor.h2" +#line 205 "cpp2taylor.h2" }; +template [[nodiscard]] auto to_string(taylor const& o) -> std::string; + +#line 218 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H @@ -150,12 +161,21 @@ auto i{2}; } #line 27 "cpp2taylor.h2" - template [[nodiscard]] auto taylor::operator[](cpp2::impl::in i) & -> auto&&{ - if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = 1, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } - return CPP2_ASSERT_IN_BOUNDS(v, i - 1); + template auto taylor::set(cpp2::impl::in k, cpp2::impl::in value) & -> void{ + if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } + CPP2_ASSERT_IN_BOUNDS(v, k - 1) = value; +{ +auto i{2}; + +#line 32 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { + CPP2_ASSERT_IN_BOUNDS(v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(v, k - 1)),i); + } +} +#line 35 "cpp2taylor.h2" } -#line 34 "cpp2taylor.h2" +#line 39 "cpp2taylor.h2" template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 0, _1 = i, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } @@ -166,62 +186,72 @@ auto i{2}; return CPP2_ASSERT_IN_BOUNDS(v, i - 1); } -#line 44 "cpp2taylor.h2" +#line 50 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator+(cpp2::impl::in o) const& -> taylor{ + return add(o, 0.0, 0.0); // Primal values are not required. + } + +#line 55 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator-(cpp2::impl::in o) const& -> taylor{ + return sub(o, 0.0, 0.0); // Primal values are not required. + } + +#line 59 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 48 "cpp2taylor.h2" +#line 63 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } -#line 52 "cpp2taylor.h2" +#line 67 "cpp2taylor.h2" return r; } -#line 55 "cpp2taylor.h2" +#line 70 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 59 "cpp2taylor.h2" +#line 74 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } -#line 63 "cpp2taylor.h2" +#line 78 "cpp2taylor.h2" return r; } -#line 66 "cpp2taylor.h2" +#line 81 "cpp2taylor.h2" template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 70 "cpp2taylor.h2" +#line 85 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{0}; -#line 72 "cpp2taylor.h2" +#line 87 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } -#line 75 "cpp2taylor.h2" +#line 90 "cpp2taylor.h2" } } -#line 76 "cpp2taylor.h2" +#line 91 "cpp2taylor.h2" return r; } -#line 79 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; @@ -230,26 +260,26 @@ auto j{0}; { auto k{1}; -#line 86 "cpp2taylor.h2" +#line 101 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; -#line 89 "cpp2taylor.h2" +#line 104 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } -#line 92 "cpp2taylor.h2" +#line 107 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 94 "cpp2taylor.h2" +#line 109 "cpp2taylor.h2" return r; } -#line 97 "cpp2taylor.h2" +#line 112 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; @@ -258,27 +288,27 @@ auto j{0}; { auto k{1}; -#line 104 "cpp2taylor.h2" +#line 119 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; -#line 107 "cpp2taylor.h2" +#line 122 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } -#line 110 "cpp2taylor.h2" +#line 125 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 113 "cpp2taylor.h2" +#line 128 "cpp2taylor.h2" return r; } -#line 116 "cpp2taylor.h2" +#line 131 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; @@ -287,27 +317,27 @@ auto j{1}; { auto k{1}; -#line 123 "cpp2taylor.h2" +#line 138 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; -#line 126 "cpp2taylor.h2" +#line 141 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } -#line 129 "cpp2taylor.h2" +#line 144 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } -#line 132 "cpp2taylor.h2" +#line 147 "cpp2taylor.h2" return r; } -#line 135 "cpp2taylor.h2" +#line 150 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; @@ -316,52 +346,52 @@ auto j{1}; { auto k{1}; -#line 142 "cpp2taylor.h2" +#line 157 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 144 "cpp2taylor.h2" +#line 159 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } -#line 147 "cpp2taylor.h2" +#line 162 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } -#line 150 "cpp2taylor.h2" +#line 165 "cpp2taylor.h2" return r; } -#line 154 "cpp2taylor.h2" +#line 169 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; -#line 159 "cpp2taylor.h2" +#line 174 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 161 "cpp2taylor.h2" +#line 176 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); } } -#line 165 "cpp2taylor.h2" +#line 180 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } -#line 168 "cpp2taylor.h2" +#line 183 "cpp2taylor.h2" } -#line 171 "cpp2taylor.h2" +#line 186 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -372,7 +402,7 @@ auto j{1}; return r; } -#line 181 "cpp2taylor.h2" +#line 196 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -383,7 +413,23 @@ auto j{1}; return r; } -#line 192 "cpp2taylor.h2" +#line 207 "cpp2taylor.h2" +template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ + std::string r {"("}; +{ +auto i{1}; + +#line 210 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { + r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; + } +} +#line 213 "cpp2taylor.h2" + r += " )"; + + return r; +} + } #endif diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index 56afac7f5..cf122bd87 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -24,9 +24,14 @@ taylor: type = { return r; } - operator[]: (inout this, i: int) -> forward_ref _ = { - assert(1 <= 1 <= dim); - return v[i - 1]; + set: (inout this, k: int, value: R) = { + assert(1 <= k <= dim); + v[k - 1] = value; + + (copy i := 2) + while i <= k next i += 1 { + v[k - 1] /= i; + } } // C++2 interface / AD interface @@ -41,6 +46,16 @@ taylor: type = { return v[i - 1]; } + // Overload for simple handling of connected adds. + operator+: (this, o: taylor) -> taylor = { + return add(o, 0.0, 0.0); // Primal values are not required. + } + + // Overload for simple handling of connected minuses. + operator-: (this, o: taylor) -> taylor = { + return sub(o, 0.0, 0.0); // Primal values are not required. + } + add: (this, o: taylor, v0: R, o0: R) -> taylor = { r: taylor = (); @@ -189,6 +204,17 @@ taylor: type = { } } +to_string: (o: taylor) -> std::string = { + r : std::string = "("; + (copy i := 1) + while i <= order next i += 1 { + r += " (o[i])$"; + } + r += " )"; + + return r; +} + } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H \ No newline at end of file diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 new file mode 100644 index 000000000..fd4d72ac1 --- /dev/null +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -0,0 +1,70 @@ + +ad_order : int == 6; +ad_type : type == cpp2::taylor; + +ad_test: @autodiff<"order=6"> @print type = { + + add_1: (x: double, y: double) -> (r: double) = { + r = x + y; + } + + add_2: (x: double, y: double) -> (r: double) = { + r = x + y + x; + } + + sub_1: (x: double, y: double) -> (r: double) = { + r = x - y; + } + + sub_2: (x: double, y: double) -> (r: double) = { + r = x - y - x; + } + + add_sub_2: (x: double, y: double) -> (r: double) = { + r = x + y - x; + } +} + +write_output: (func: std::string, x: double, x_d: ad_type, y: double, y_d: ad_type, ret) = { + std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$):" << std::endl; + std::cout << " r = (ret.r)$" << std::endl; + (copy i:=1) + while i <= ad_order next i += 1 { + std::cout << " d(i)$ = (ret.r_d[i])$" << std::endl; + } +} + +main: () = { + + + x: double = 2.0; + x_d: ad_type = 1.0; + y: double = 3.0; + y_d: ad_type = 2.0; + + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); +// write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); +// write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); +// write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); +// write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); +// write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); +// write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); +// write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); +// write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); +// write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); +// write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); +// write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); +// write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); +// write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); +// write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); +// write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); +// write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); +// write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); +// write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); +// write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); +// write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); +} diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution new file mode 100644 index 000000000..32df76b0d --- /dev/null +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -0,0 +1,40 @@ +diff(x + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y + x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 7.000000 + d1 = 4.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -1.000000 + d1 = -1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -3.000000 + d1 = -2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp new file mode 100644 index 000000000..7fdb306ad --- /dev/null +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -0,0 +1,208 @@ + +#define CPP2_IMPORT_STD Yes +#include "cpp2taylor.h" + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-autodiff-higher-order.cpp2" + +#line 5 "pure2-autodiff-higher-order.cpp2" +class ad_test; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-autodiff-higher-order.cpp2" + +#line 2 "pure2-autodiff-higher-order.cpp2" +int inline constexpr ad_order{ 6 }; +using ad_type = cpp2::taylor; + +class ad_test { +using add_1_ret = double; + + +#line 7 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; +using add_2_ret = double; + + +#line 11 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; +using sub_1_ret = double; + + +#line 15 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; +using sub_2_ret = double; + + +#line 19 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; +using add_sub_2_ret = double; + + +#line 23 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; +struct add_1_d_ret { double r; cpp2::taylor r_d; }; + + + public: [[nodiscard]] static auto add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret; + +struct add_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto add_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_2_d_ret; + +struct sub_1_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto sub_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_1_d_ret; + +struct sub_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_2_d_ret; + +struct add_sub_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto add_sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_sub_2_d_ret; + + public: ad_test() = default; + public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(ad_test const&) -> void = delete; + + +#line 26 "pure2-autodiff-higher-order.cpp2" +}; + +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; + +#line 37 "pure2-autodiff-higher-order.cpp2" +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-autodiff-higher-order.cpp2" + +#line 7 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ + cpp2::impl::deferred_init r; +#line 8 "pure2-autodiff-higher-order.cpp2" + r.construct(x + y); + return std::move(r.value()); } + +#line 11 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ + cpp2::impl::deferred_init r; +#line 12 "pure2-autodiff-higher-order.cpp2" + r.construct(x + y + x); + return std::move(r.value()); } + +#line 15 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ + cpp2::impl::deferred_init r; +#line 16 "pure2-autodiff-higher-order.cpp2" + r.construct(x - y); + return std::move(r.value()); } + +#line 19 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ + cpp2::impl::deferred_init r; +#line 20 "pure2-autodiff-higher-order.cpp2" + r.construct(x - y - x); + return std::move(r.value()); } + +#line 23 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ + cpp2::impl::deferred_init r; +#line 24 "pure2-autodiff-higher-order.cpp2" + r.construct(x + y - x); + return std::move(r.value()); } + + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::add_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d + x_d; + r = x + y + x; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::sub_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_1_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d - y_d; + r = x - y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d - y_d - x_d; + r = x - y - x; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::add_sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_sub_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d - x_d; + r = x + y - x; + return { std::move(r), std::move(r_d) }; + } + +#line 28 "pure2-autodiff-higher-order.cpp2" +auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ + std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; + std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; +{ +auto i{1}; + +#line 32 "pure2-autodiff-higher-order.cpp2" + for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { + std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; + } +} +#line 35 "pure2-autodiff-higher-order.cpp2" +} + +#line 37 "pure2-autodiff-higher-order.cpp2" +auto main() -> int{ + +#line 40 "pure2-autodiff-higher-order.cpp2" + double x {2.0}; + ad_type x_d {1.0}; + double y {3.0}; + ad_type y_d {2.0}; + + write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); +// write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); +// write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); +// write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); +// write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); +// write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); +// write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); +// write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); +// write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); +// write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); +// write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); +// write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); +// write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); +// write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); +// write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); +// write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); +// write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); +// write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); +// write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); +// write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); +// write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); +} + diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output new file mode 100644 index 000000000..48eed81da --- /dev/null +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -0,0 +1,126 @@ +pure2-autodiff-higher-order.cpp2... + +ad_test:/* @autodiff<"order=6"> @print */ type = +{ + add_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y; + return; + } + + add_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y + x; + return; + } + + sub_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y; + return; + } + + sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y - x; + return; + } + + add_sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y - x; + return; + } + + add_1_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } + + add_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d + y_d + x_d; + r = x + y + x; + return; + } + + sub_1_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d - y_d; + r = x - y; + return; + } + + sub_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d - y_d - x_d; + r = x - y - x; + return; + } + + add_sub_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d + y_d - x_d; + r = x + y - x; + return; + } +} + ok (all Cpp2, passes safety checks) + diff --git a/source/reflect.h b/source/reflect.h index 943f3cba9..582893432 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -115,88 +115,88 @@ class autodiff_special_func; class autodiff_context; -#line 4037 "reflect.h2" +#line 4061 "reflect.h2" class autodiff_handler_base; -#line 4051 "reflect.h2" +#line 4075 "reflect.h2" class autodiff_expression_handler; -#line 4444 "reflect.h2" +#line 4468 "reflect.h2" class autodiff_stmt_handler; -#line 4807 "reflect.h2" +#line 4851 "reflect.h2" class expression_flags; -#line 4823 "reflect.h2" +#line 4867 "reflect.h2" class regex_token; -#line 4850 "reflect.h2" +#line 4894 "reflect.h2" class regex_token_check; -#line 4871 "reflect.h2" +#line 4915 "reflect.h2" class regex_token_code; -#line 4892 "reflect.h2" +#line 4936 "reflect.h2" class regex_token_empty; -#line 4910 "reflect.h2" +#line 4954 "reflect.h2" class regex_token_list; -#line 4962 "reflect.h2" +#line 5006 "reflect.h2" class parse_context_group_state; -#line 5023 "reflect.h2" +#line 5067 "reflect.h2" class parse_context_branch_reset_state; -#line 5066 "reflect.h2" +#line 5110 "reflect.h2" class parse_context; -#line 5467 "reflect.h2" +#line 5511 "reflect.h2" class generation_function_context; -#line 5485 "reflect.h2" +#line 5529 "reflect.h2" class generation_context; -#line 5684 "reflect.h2" +#line 5728 "reflect.h2" class alternative_token; -#line 5699 "reflect.h2" +#line 5743 "reflect.h2" class alternative_token_gen; -#line 5764 "reflect.h2" +#line 5808 "reflect.h2" class any_token; -#line 5781 "reflect.h2" +#line 5825 "reflect.h2" class atomic_group_token; -#line 5811 "reflect.h2" +#line 5855 "reflect.h2" class char_token; -#line 5926 "reflect.h2" +#line 5970 "reflect.h2" class class_token; -#line 6150 "reflect.h2" +#line 6194 "reflect.h2" class group_ref_token; -#line 6287 "reflect.h2" +#line 6331 "reflect.h2" class group_token; -#line 6634 "reflect.h2" +#line 6678 "reflect.h2" class lookahead_lookbehind_token; -#line 6729 "reflect.h2" +#line 6773 "reflect.h2" class range_token; -#line 6886 "reflect.h2" +#line 6930 "reflect.h2" class special_range_token; -#line 6972 "reflect.h2" +#line 7016 "reflect.h2" template class regex_generator; -#line 7229 "reflect.h2" +#line 7273 "reflect.h2" } } @@ -1686,23 +1686,36 @@ class autodiff_context { #line 4007 "reflect.h2" public: std::string suffix {"_d"}; + private: int order {1}; + +#line 4011 "reflect.h2" + public: std::string ad_type {"double"}; + public: auto set_order(cpp2::impl::in new_order) & -> void; + +#line 4024 "reflect.h2" public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4015 "reflect.h2" +#line 4030 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4022 "reflect.h2" +#line 4039 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; + +#line 4053 "reflect.h2" + public: auto enter_function() & -> void; + +#line 4057 "reflect.h2" + public: auto leave_function() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4035 "reflect.h2" +#line 4059 "reflect.h2" }; class autodiff_handler_base { @@ -1711,21 +1724,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4042 "reflect.h2" +#line 4066 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4046 "reflect.h2" +#line 4070 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4049 "reflect.h2" +#line 4073 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4055 "reflect.h2" +#line 4079 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1734,180 +1747,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4072 "reflect.h2" +#line 4096 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4091 "reflect.h2" +#line 4115 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4100 "reflect.h2" +#line 4124 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4138 "reflect.h2" +#line 4162 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4235 "reflect.h2" +#line 4259 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4268 "reflect.h2" +#line 4292 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4272 "reflect.h2" +#line 4296 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4276 "reflect.h2" +#line 4300 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4280 "reflect.h2" +#line 4304 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4284 "reflect.h2" +#line 4308 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4288 "reflect.h2" +#line 4312 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4292 "reflect.h2" +#line 4316 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4296 "reflect.h2" +#line 4320 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4300 "reflect.h2" +#line 4324 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4304 "reflect.h2" +#line 4328 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4308 "reflect.h2" +#line 4332 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4312 "reflect.h2" +#line 4336 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4335 "reflect.h2" +#line 4359 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4378 "reflect.h2" +#line 4402 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4382 "reflect.h2" +#line 4406 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4387 "reflect.h2" +#line 4411 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4414 "reflect.h2" +#line 4438 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4442 "reflect.h2" +#line 4466 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4448 "reflect.h2" +#line 4472 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4457 "reflect.h2" +#line 4481 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4462 "reflect.h2" +#line 4486 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4467 "reflect.h2" +#line 4491 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4485 "reflect.h2" +#line 4509 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4490 "reflect.h2" +#line 4514 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4495 "reflect.h2" +#line 4519 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4500 "reflect.h2" +#line 4524 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4508 "reflect.h2" +#line 4532 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4524 "reflect.h2" +#line 4548 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4571 "reflect.h2" +#line 4595 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4582 "reflect.h2" +#line 4606 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4610 "reflect.h2" +#line 4634 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4615 "reflect.h2" +#line 4639 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4619 "reflect.h2" +#line 4643 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4623 "reflect.h2" +#line 4647 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4627 "reflect.h2" +#line 4651 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4631 "reflect.h2" +#line 4655 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4635 "reflect.h2" +#line 4659 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4639 "reflect.h2" +#line 4663 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4643 "reflect.h2" +#line 4667 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4647 "reflect.h2" +#line 4671 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4651 "reflect.h2" +#line 4675 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4655 "reflect.h2" +#line 4679 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4659 "reflect.h2" +#line 4683 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4663 "reflect.h2" +#line 4687 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4668 "reflect.h2" +#line 4692 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4697 "reflect.h2" +#line 4721 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4701 "reflect.h2" +#line 4725 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4803 "reflect.h2" +#line 4847 "reflect.h2" using error_func = std::function x)>; -#line 4807 "reflect.h2" +#line 4851 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1942,20 +1955,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4815 "reflect.h2" +#line 4859 "reflect.h2" }; -#line 4823 "reflect.h2" +#line 4867 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4831 "reflect.h2" +#line 4875 "reflect.h2" public: explicit regex_token(); -#line 4836 "reflect.h2" +#line 4880 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1967,103 +1980,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4842 "reflect.h2" +#line 4886 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4848 "reflect.h2" +#line 4892 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4854 "reflect.h2" +#line 4898 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4861 "reflect.h2" +#line 4905 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4865 "reflect.h2" +#line 4909 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4866 "reflect.h2" +#line 4910 "reflect.h2" }; -#line 4869 "reflect.h2" +#line 4913 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4875 "reflect.h2" +#line 4919 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4882 "reflect.h2" +#line 4926 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4886 "reflect.h2" +#line 4930 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4887 "reflect.h2" +#line 4931 "reflect.h2" }; -#line 4890 "reflect.h2" +#line 4934 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4896 "reflect.h2" +#line 4940 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4900 "reflect.h2" +#line 4944 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4904 "reflect.h2" +#line 4948 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4905 "reflect.h2" +#line 4949 "reflect.h2" }; -#line 4908 "reflect.h2" +#line 4952 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4914 "reflect.h2" +#line 4958 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4921 "reflect.h2" +#line 4965 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4927 "reflect.h2" +#line 4971 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4933 "reflect.h2" +#line 4977 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4941 "reflect.h2" +#line 4985 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2071,10 +2084,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4953 "reflect.h2" +#line 4997 "reflect.h2" }; -#line 4956 "reflect.h2" +#line 5000 "reflect.h2" // // Parse and generation context. // @@ -2090,33 +2103,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 4976 "reflect.h2" +#line 5020 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 4983 "reflect.h2" +#line 5027 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 4995 "reflect.h2" +#line 5039 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5000 "reflect.h2" +#line 5044 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5004 "reflect.h2" +#line 5048 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5018 "reflect.h2" +#line 5062 "reflect.h2" }; -#line 5021 "reflect.h2" +#line 5065 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2129,25 +2142,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5039 "reflect.h2" +#line 5083 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5045 "reflect.h2" +#line 5089 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5052 "reflect.h2" +#line 5096 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5059 "reflect.h2" +#line 5103 "reflect.h2" }; -#line 5062 "reflect.h2" +#line 5106 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2163,7 +2176,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5078 "reflect.h2" +#line 5122 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2171,64 +2184,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5089 "reflect.h2" +#line 5133 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5102 "reflect.h2" +#line 5146 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5110 "reflect.h2" +#line 5154 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5114 "reflect.h2" +#line 5158 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5118 "reflect.h2" +#line 5162 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5130 "reflect.h2" +#line 5174 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5137 "reflect.h2" +#line 5181 "reflect.h2" public: auto next_alternative() & -> void; -#line 5143 "reflect.h2" +#line 5187 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5149 "reflect.h2" +#line 5193 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5153 "reflect.h2" +#line 5197 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5164 "reflect.h2" +#line 5208 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5168 "reflect.h2" +#line 5212 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5174 "reflect.h2" +#line 5218 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5178 "reflect.h2" +#line 5222 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5185 "reflect.h2" +#line 5229 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5196 "reflect.h2" +#line 5240 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2236,51 +2249,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5240 "reflect.h2" +#line 5284 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5252 "reflect.h2" +#line 5296 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5265 "reflect.h2" +#line 5309 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5288 "reflect.h2" +#line 5332 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5305 "reflect.h2" +#line 5349 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5326 "reflect.h2" +#line 5370 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5336 "reflect.h2" +#line 5380 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5340 "reflect.h2" +#line 5384 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5396 "reflect.h2" +#line 5440 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5435 "reflect.h2" +#line 5479 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5450 "reflect.h2" +#line 5494 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2292,10 +2305,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5461 "reflect.h2" +#line 5505 "reflect.h2" }; -#line 5464 "reflect.h2" +#line 5508 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2305,16 +2318,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5478 "reflect.h2" +#line 5522 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5481 "reflect.h2" +#line 5525 "reflect.h2" }; -#line 5484 "reflect.h2" +#line 5528 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2334,68 +2347,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5506 "reflect.h2" +#line 5550 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5512 "reflect.h2" +#line 5556 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5521 "reflect.h2" +#line 5565 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5532 "reflect.h2" +#line 5576 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5539 "reflect.h2" +#line 5583 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5559 "reflect.h2" +#line 5603 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5569 "reflect.h2" +#line 5613 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5592 "reflect.h2" +#line 5636 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5600 "reflect.h2" +#line 5644 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5604 "reflect.h2" +#line 5648 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5610 "reflect.h2" +#line 5654 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5616 "reflect.h2" +#line 5660 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5626 "reflect.h2" +#line 5670 "reflect.h2" public: auto finish_context() & -> void; -#line 5634 "reflect.h2" +#line 5678 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5640 "reflect.h2" +#line 5684 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5644 "reflect.h2" +#line 5688 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5648 "reflect.h2" +#line 5692 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5672 "reflect.h2" +#line 5716 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2403,7 +2416,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5678 "reflect.h2" +#line 5722 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2423,27 +2436,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5697 "reflect.h2" +#line 5741 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5703 "reflect.h2" +#line 5747 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5710 "reflect.h2" +#line 5754 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5727 "reflect.h2" +#line 5771 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5734 "reflect.h2" +#line 5778 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5747 "reflect.h2" +#line 5791 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2451,19 +2464,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5759 "reflect.h2" +#line 5803 "reflect.h2" }; -#line 5762 "reflect.h2" +#line 5806 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5768 "reflect.h2" +#line 5812 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5772 "reflect.h2" +#line 5816 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2471,7 +2484,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5777 "reflect.h2" +#line 5821 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2479,17 +2492,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5785 "reflect.h2" +#line 5829 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5796 "reflect.h2" +#line 5840 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5804 "reflect.h2" +#line 5848 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2497,7 +2510,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5807 "reflect.h2" +#line 5851 "reflect.h2" }; // Regex syntax: a @@ -2505,34 +2518,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5815 "reflect.h2" +#line 5859 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5824 "reflect.h2" +#line 5868 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5830 "reflect.h2" +#line 5874 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5834 "reflect.h2" +#line 5878 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5857 "reflect.h2" +#line 5901 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5878 "reflect.h2" +#line 5922 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5896 "reflect.h2" +#line 5940 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5911 "reflect.h2" +#line 5955 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5917 "reflect.h2" +#line 5961 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2540,33 +2553,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5921 "reflect.h2" +#line 5965 "reflect.h2" }; -#line 5924 "reflect.h2" +#line 5968 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5930 "reflect.h2" +#line 5974 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5942 "reflect.h2" +#line 5986 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6068 "reflect.h2" +#line 6112 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6077 "reflect.h2" +#line 6121 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6082 "reflect.h2" +#line 6126 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2574,20 +2587,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6089 "reflect.h2" +#line 6133 "reflect.h2" }; -#line 6092 "reflect.h2" +#line 6136 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6133 "reflect.h2" +#line 6177 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6144 "reflect.h2" +#line 6188 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2597,20 +2610,20 @@ class class_token class group_ref_token : public regex_token { -#line 6154 "reflect.h2" +#line 6198 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6166 "reflect.h2" +#line 6210 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6267 "reflect.h2" +#line 6311 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6271 "reflect.h2" +#line 6315 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2618,10 +2631,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6274 "reflect.h2" +#line 6318 "reflect.h2" }; -#line 6277 "reflect.h2" +#line 6321 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2635,29 +2648,29 @@ class group_ref_token class group_token : public regex_token { -#line 6291 "reflect.h2" +#line 6335 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6313 "reflect.h2" +#line 6357 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6327 "reflect.h2" +#line 6371 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6486 "reflect.h2" +#line 6530 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6494 "reflect.h2" +#line 6538 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6512 "reflect.h2" +#line 6556 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6543 "reflect.h2" +#line 6587 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2666,25 +2679,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6550 "reflect.h2" +#line 6594 "reflect.h2" }; -#line 6553 "reflect.h2" +#line 6597 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6594 "reflect.h2" +#line 6638 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6614 "reflect.h2" +#line 6658 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6630 "reflect.h2" +#line 6674 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2692,20 +2705,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6638 "reflect.h2" +#line 6682 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6647 "reflect.h2" +#line 6691 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6658 "reflect.h2" +#line 6702 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6665 "reflect.h2" +#line 6709 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2713,26 +2726,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6668 "reflect.h2" +#line 6712 "reflect.h2" }; -#line 6671 "reflect.h2" +#line 6715 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6699 "reflect.h2" +#line 6743 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6727 "reflect.h2" +#line 6771 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6733 "reflect.h2" +#line 6777 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2742,22 +2755,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6813 "reflect.h2" +#line 6857 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6825 "reflect.h2" +#line 6869 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6838 "reflect.h2" +#line 6882 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6857 "reflect.h2" +#line 6901 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6867 "reflect.h2" +#line 6911 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6878 "reflect.h2" +#line 6922 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2765,16 +2778,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6881 "reflect.h2" +#line 6925 "reflect.h2" }; -#line 6884 "reflect.h2" +#line 6928 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6890 "reflect.h2" +#line 6934 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2783,7 +2796,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6920 "reflect.h2" +#line 6964 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2792,14 +2805,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6942 "reflect.h2" +#line 6986 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 6964 "reflect.h2" +#line 7008 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2820,24 +2833,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 6987 "reflect.h2" +#line 7031 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7022 "reflect.h2" +#line 7066 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7036 "reflect.h2" +#line 7080 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7048 "reflect.h2" +#line 7092 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7103 "reflect.h2" +#line 7147 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2848,7 +2861,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7229 "reflect.h2" +#line 7273 "reflect.h2" } } @@ -7473,26 +7486,43 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 4002 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4009 "reflect.h2" +#line 4010 "reflect.h2" + // Members depending on order + +#line 4013 "reflect.h2" + auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ + order = new_order; + + if (1 == order) { + ad_type = "double"; + } + else { + ad_type = "cpp2::taylor"; + } + } + +#line 4024 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4015 "reflect.h2" +#line 4030 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ - // TODO: Add type to required generation for AD. + if (order == 1) { + return type; // Same type for now for order 1 + } - return type; // Use the same type for now. + return string_util::replace_all(type, "double", ad_type); } -#line 4022 "reflect.h2" +#line 4039 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4023 "reflect.h2" +#line 4040 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7506,27 +7536,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return { std::move(m.value()), std::move(code.value()) }; } -#line 4042 "reflect.h2" +#line 4053 "reflect.h2" + auto autodiff_context::enter_function() & -> void{ + temporary_count = 0; + } + +#line 4057 "reflect.h2" + auto autodiff_context::leave_function() & -> void{ + } + +#line 4066 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4044 "reflect.h2" +#line 4068 "reflect.h2" } -#line 4042 "reflect.h2" +#line 4066 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4044 "reflect.h2" +#line 4068 "reflect.h2" } -#line 4046 "reflect.h2" +#line 4070 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4061 "reflect.h2" +#line 4085 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7534,13 +7573,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4067 "reflect.h2" +#line 4091 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4072 "reflect.h2" +#line 4096 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7560,7 +7599,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4091 "reflect.h2" +#line 4115 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7570,7 +7609,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4100 "reflect.h2" +#line 4124 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7609,7 +7648,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4138 "reflect.h2" +#line 4162 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7617,7 +7656,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4144 "reflect.h2" +#line 4168 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7631,7 +7670,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4156 "reflect.h2" +#line 4180 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7654,7 +7693,7 @@ auto i{0}; { auto i{0}; -#line 4177 "reflect.h2" +#line 4201 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7679,7 +7718,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4200 "reflect.h2" +#line 4224 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7715,7 +7754,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation. } -#line 4235 "reflect.h2" +#line 4259 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7740,75 +7779,75 @@ auto i{0}; { auto i{1}; -#line 4258 "reflect.h2" +#line 4282 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4263 "reflect.h2" +#line 4287 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4268 "reflect.h2" +#line 4292 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4272 "reflect.h2" +#line 4296 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4276 "reflect.h2" +#line 4300 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4280 "reflect.h2" +#line 4304 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4284 "reflect.h2" +#line 4308 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4288 "reflect.h2" +#line 4312 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4292 "reflect.h2" +#line 4316 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4296 "reflect.h2" +#line 4320 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4300 "reflect.h2" +#line 4324 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4304 "reflect.h2" +#line 4328 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4308 "reflect.h2" +#line 4332 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4312 "reflect.h2" +#line 4336 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7832,7 +7871,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4335 "reflect.h2" +#line 4359 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7859,7 +7898,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4362 "reflect.h2" +#line 4386 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7876,18 +7915,18 @@ auto i{1}; } } -#line 4378 "reflect.h2" +#line 4402 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4382 "reflect.h2" +#line 4406 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4387 "reflect.h2" +#line 4411 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7896,7 +7935,7 @@ auto i{1}; { auto i{0}; -#line 4394 "reflect.h2" +#line 4418 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7910,7 +7949,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4406 "reflect.h2" +#line 4430 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7919,7 +7958,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4414 "reflect.h2" +#line 4438 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7949,26 +7988,26 @@ auto i{0}; }}}} } -#line 4452 "reflect.h2" +#line 4476 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4455 "reflect.h2" +#line 4479 "reflect.h2" } -#line 4457 "reflect.h2" +#line 4481 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4462 "reflect.h2" +#line 4486 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4467 "reflect.h2" +#line 4491 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -7986,22 +8025,22 @@ auto i{0}; } } -#line 4485 "reflect.h2" +#line 4509 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4490 "reflect.h2" +#line 4514 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4495 "reflect.h2" +#line 4519 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4500 "reflect.h2" +#line 4524 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8009,7 +8048,7 @@ auto i{0}; diff += "}\n"; } -#line 4508 "reflect.h2" +#line 4532 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8025,7 +8064,7 @@ auto i{0}; } } -#line 4524 "reflect.h2" +#line 4548 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8072,7 +8111,7 @@ auto i{0}; }} } -#line 4571 "reflect.h2" +#line 4595 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8084,7 +8123,7 @@ auto i{0}; } } -#line 4582 "reflect.h2" +#line 4606 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8113,79 +8152,79 @@ auto i{0}; } } -#line 4610 "reflect.h2" +#line 4634 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4615 "reflect.h2" +#line 4639 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4619 "reflect.h2" +#line 4643 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4623 "reflect.h2" +#line 4647 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4627 "reflect.h2" +#line 4651 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4631 "reflect.h2" +#line 4655 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4635 "reflect.h2" +#line 4659 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4639 "reflect.h2" +#line 4663 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4643 "reflect.h2" +#line 4667 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4647 "reflect.h2" +#line 4671 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4651 "reflect.h2" +#line 4675 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4655 "reflect.h2" +#line 4679 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4659 "reflect.h2" +#line 4683 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4663 "reflect.h2" +#line 4687 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4668 "reflect.h2" +#line 4692 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8194,7 +8233,7 @@ auto i{0}; { auto i{0}; -#line 4675 "reflect.h2" +#line 4699 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8208,7 +8247,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4687 "reflect.h2" +#line 4711 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8219,27 +8258,36 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4697 "reflect.h2" +#line 4721 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4703 "reflect.h2" +#line 4727 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { std::string_view constexpr suffix_token{ "suffix=" }; + std::string_view constexpr order_token{ "order=" }; auto args {CPP2_UFCS(get_arguments)(t)}; std::string suffix {"_d"}; + int order {1}; for ( auto const& arg_str : cpp2::move(args) ) { if (CPP2_UFCS(starts_with)(arg_str, "\"") && CPP2_UFCS(ends_with)(arg_str, "\"")) { auto arg {CPP2_UFCS(substr)(arg_str, 1, CPP2_UFCS(ssize)(arg_str) - 2)}; if (CPP2_UFCS(starts_with)(arg, suffix_token)) { - suffix = CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(suffix_token)); + suffix = CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(suffix_token)); + continue; + } + if (CPP2_UFCS(starts_with)(arg, order_token)) { + if (!(string_util::string_to_int(CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(order_token)), order))) { + CPP2_UFCS(error)(t, "AD: Could not parse derivative order: " + cpp2::to_string(CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(order_token))) + ""); + return ; + } continue; } } @@ -8248,12 +8296,18 @@ auto autodiff(meta::type_declaration& t) -> void return ; } + autodiff_context ad_ctx {}; + ad_ctx.suffix = suffix; + CPP2_UFCS(set_order)(ad_ctx, order); + for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_function)(m)) { auto mf {CPP2_UFCS(as_function)(m)}; + CPP2_UFCS(enter_function)(ad_ctx); + std::string diff {" " + cpp2::to_string(CPP2_UFCS(name)(mf)) + cpp2::to_string(suffix) + ": ("}; // 1. Generate the modified signature @@ -8261,7 +8315,7 @@ auto autodiff(meta::type_declaration& t) -> void for ( auto const& param : CPP2_UFCS(get_parameters)(mf) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + ", "; } diff += ") -> ("; @@ -8281,7 +8335,7 @@ auto autodiff(meta::type_declaration& t) -> void else { for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + " = 0.0, "; } } @@ -8294,11 +8348,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } - autodiff_context ad_ctx {}; - ad_ctx.suffix = suffix; +#line 4811 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4776 "reflect.h2" +#line 4814 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8307,8 +8360,14 @@ auto autodiff(meta::type_declaration& t) -> void diff += "}"; + CPP2_UFCS(leave_function)(ad_ctx); + CPP2_UFCS(add_member)(t, cpp2::move(diff)); } + + if (1 != cpp2::move(order)) { + CPP2_UFCS(add_runtime_support_include)(t, "cpp2taylor.h"); + } } @@ -8402,7 +8461,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4789 "reflect.h2" +#line 4833 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8418,11 +8477,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4805 "reflect.h2" +#line 4849 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4809 "reflect.h2" +#line 4853 "reflect.h2" // mod: i // mod: m // mod: s @@ -8430,116 +8489,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4818 "reflect.h2" +#line 4862 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4827 "reflect.h2" +#line 4871 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4829 "reflect.h2" +#line 4873 "reflect.h2" } -#line 4831 "reflect.h2" +#line 4875 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4833 "reflect.h2" +#line 4877 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4839 "reflect.h2" +#line 4883 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4840 "reflect.h2" +#line 4884 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4841 "reflect.h2" +#line 4885 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4856 "reflect.h2" +#line 4900 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4859 "reflect.h2" +#line 4903 "reflect.h2" } -#line 4861 "reflect.h2" +#line 4905 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4865 "reflect.h2" +#line 4909 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4877 "reflect.h2" +#line 4921 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4880 "reflect.h2" +#line 4924 "reflect.h2" } -#line 4882 "reflect.h2" +#line 4926 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4886 "reflect.h2" +#line 4930 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4896 "reflect.h2" +#line 4940 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4898 "reflect.h2" +#line 4942 "reflect.h2" } -#line 4900 "reflect.h2" +#line 4944 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4904 "reflect.h2" +#line 4948 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4916 "reflect.h2" +#line 4960 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4919 "reflect.h2" +#line 4963 "reflect.h2" } -#line 4921 "reflect.h2" +#line 4965 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4927 "reflect.h2" +#line 4971 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4933 "reflect.h2" +#line 4977 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8548,7 +8607,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4941 "reflect.h2" +#line 4985 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8564,7 +8623,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 4969 "reflect.h2" +#line 5013 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8572,14 +8631,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 4977 "reflect.h2" +#line 5021 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 4984 "reflect.h2" +#line 5028 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8591,15 +8650,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 4996 "reflect.h2" +#line 5040 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5001 "reflect.h2" +#line 5045 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5005 "reflect.h2" +#line 5049 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8620,7 +8679,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5031 "reflect.h2" +#line 5075 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8629,20 +8688,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5040 "reflect.h2" +#line 5084 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5046 "reflect.h2" +#line 5090 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5053 "reflect.h2" +#line 5097 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8657,16 +8716,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5083 "reflect.h2" +#line 5127 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5087 "reflect.h2" +#line 5131 "reflect.h2" } -#line 5093 "reflect.h2" +#line 5137 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8676,7 +8735,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5103 "reflect.h2" +#line 5147 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8684,17 +8743,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5110 "reflect.h2" +#line 5154 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5114 "reflect.h2" +#line 5158 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5121 "reflect.h2" +#line 5165 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8704,7 +8763,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5130 "reflect.h2" +#line 5174 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8712,24 +8771,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5137 "reflect.h2" +#line 5181 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5145 "reflect.h2" +#line 5189 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5149 "reflect.h2" +#line 5193 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5153 "reflect.h2" +#line 5197 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8741,22 +8800,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5164 "reflect.h2" +#line 5208 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5170 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5174 "reflect.h2" +#line 5218 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5178 "reflect.h2" +#line 5222 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8764,7 +8823,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5185 "reflect.h2" +#line 5229 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8776,10 +8835,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5198 "reflect.h2" +#line 5242 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5201 "reflect.h2" +#line 5245 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8819,7 +8878,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5241 "reflect.h2" +#line 5285 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8831,14 +8890,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5252 "reflect.h2" +#line 5296 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5253 "reflect.h2" +#line 5297 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5254 "reflect.h2" +#line 5298 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5256 "reflect.h2" +#line 5300 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8848,10 +8907,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5265 "reflect.h2" +#line 5309 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5267 "reflect.h2" +#line 5311 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8873,14 +8932,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5288 "reflect.h2" +#line 5332 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5289 "reflect.h2" +#line 5333 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5290 "reflect.h2" +#line 5334 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5292 "reflect.h2" +#line 5336 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8894,7 +8953,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5305 "reflect.h2" +#line 5349 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8916,7 +8975,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5326 "reflect.h2" +#line 5370 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8927,12 +8986,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5336 "reflect.h2" +#line 5380 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5337 "reflect.h2" +#line 5381 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5342 "reflect.h2" +#line 5386 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -8987,7 +9046,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5396 "reflect.h2" +#line 5440 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9027,7 +9086,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5435 "reflect.h2" +#line 5479 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9043,21 +9102,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5452 "reflect.h2" +#line 5496 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5453 "reflect.h2" +#line 5497 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5454 "reflect.h2" +#line 5498 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5456 "reflect.h2" +#line 5500 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5471 "reflect.h2" +#line 5515 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9065,7 +9124,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5478 "reflect.h2" +#line 5522 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9075,22 +9134,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5496 "reflect.h2" +#line 5540 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5501 "reflect.h2" +#line 5545 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5507 "reflect.h2" +#line 5551 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5513 "reflect.h2" +#line 5557 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9099,7 +9158,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5521 "reflect.h2" +#line 5565 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9111,7 +9170,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5532 "reflect.h2" +#line 5576 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9119,7 +9178,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5539 "reflect.h2" +#line 5583 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9140,7 +9199,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5560 "reflect.h2" +#line 5604 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9150,7 +9209,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5570 "reflect.h2" +#line 5614 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9173,33 +9232,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5594 "reflect.h2" +#line 5638 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5600 "reflect.h2" +#line 5644 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5604 "reflect.h2" +#line 5648 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5610 "reflect.h2" +#line 5654 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5618 "reflect.h2" +#line 5662 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9208,7 +9267,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5626 "reflect.h2" +#line 5670 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9217,22 +9276,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5636 "reflect.h2" +#line 5680 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5640 "reflect.h2" +#line 5684 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5644 "reflect.h2" +#line 5688 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5648 "reflect.h2" +#line 5692 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9256,18 +9315,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5673 "reflect.h2" +#line 5717 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5688 "reflect.h2" +#line 5732 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5690 "reflect.h2" +#line 5734 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9278,15 +9337,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5705 "reflect.h2" +#line 5749 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5708 "reflect.h2" +#line 5752 "reflect.h2" } -#line 5710 "reflect.h2" +#line 5754 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9304,7 +9363,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5727 "reflect.h2" +#line 5771 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9312,7 +9371,7 @@ generation_function_context::generation_function_context(){} } } -#line 5734 "reflect.h2" +#line 5778 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9326,7 +9385,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5747 "reflect.h2" +#line 5791 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9342,14 +9401,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5768 "reflect.h2" +#line 5812 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5770 "reflect.h2" +#line 5814 "reflect.h2" } -#line 5772 "reflect.h2" +#line 5816 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9358,11 +9417,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5787 "reflect.h2" +#line 5831 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5789 "reflect.h2" +#line 5833 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9370,7 +9429,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5796 "reflect.h2" +#line 5840 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9379,37 +9438,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5804 "reflect.h2" +#line 5848 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5818 "reflect.h2" +#line 5862 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5822 "reflect.h2" +#line 5866 "reflect.h2" } -#line 5824 "reflect.h2" +#line 5868 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5828 "reflect.h2" +#line 5872 "reflect.h2" } -#line 5830 "reflect.h2" +#line 5874 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5834 "reflect.h2" +#line 5878 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9418,14 +9477,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5840 "reflect.h2" +#line 5884 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5845 "reflect.h2" +#line 5889 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9438,7 +9497,7 @@ size_t i{0}; } } -#line 5857 "reflect.h2" +#line 5901 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9460,7 +9519,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5878 "reflect.h2" +#line 5922 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9479,7 +9538,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5896 "reflect.h2" +#line 5940 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9495,14 +9554,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5911 "reflect.h2" +#line 5955 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5917 "reflect.h2" +#line 5961 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9510,19 +9569,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5934 "reflect.h2" +#line 5978 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5935 "reflect.h2" +#line 5979 "reflect.h2" { -#line 5940 "reflect.h2" +#line 5984 "reflect.h2" } -#line 5943 "reflect.h2" +#line 5987 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9648,7 +9707,7 @@ size_t i{0}; ); } -#line 6068 "reflect.h2" +#line 6112 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9658,13 +9717,13 @@ size_t i{0}; ); } -#line 6077 "reflect.h2" +#line 6121 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6082 "reflect.h2" +#line 6126 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9675,12 +9734,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6094 "reflect.h2" +#line 6138 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6099 "reflect.h2" +#line 6143 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9714,7 +9773,7 @@ size_t i{0}; } -#line 6135 "reflect.h2" +#line 6179 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9723,19 +9782,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6158 "reflect.h2" +#line 6202 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6159 "reflect.h2" +#line 6203 "reflect.h2" { -#line 6164 "reflect.h2" +#line 6208 "reflect.h2" } -#line 6166 "reflect.h2" +#line 6210 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9837,19 +9896,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6267 "reflect.h2" +#line 6311 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6271 "reflect.h2" +#line 6315 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6295 "reflect.h2" +#line 6339 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9868,7 +9927,7 @@ size_t i{0}; return r; } -#line 6313 "reflect.h2" +#line 6357 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9883,7 +9942,7 @@ size_t i{0}; return r; } -#line 6327 "reflect.h2" +#line 6371 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10043,7 +10102,7 @@ size_t i{0}; } } -#line 6486 "reflect.h2" +#line 6530 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10052,7 +10111,7 @@ size_t i{0}; return r; } -#line 6494 "reflect.h2" +#line 6538 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10071,7 +10130,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6512 "reflect.h2" +#line 6556 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10103,7 +10162,7 @@ size_t i{0}; } } -#line 6543 "reflect.h2" +#line 6587 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10114,7 +10173,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6555 "reflect.h2" +#line 6599 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10153,7 +10212,7 @@ size_t i{0}; return r; } -#line 6596 "reflect.h2" +#line 6640 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10171,7 +10230,7 @@ size_t i{0}; }} } -#line 6616 "reflect.h2" +#line 6660 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10185,16 +10244,16 @@ size_t i{0}; } } -#line 6642 "reflect.h2" +#line 6686 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6645 "reflect.h2" +#line 6689 "reflect.h2" } -#line 6647 "reflect.h2" +#line 6691 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10206,7 +10265,7 @@ size_t i{0}; } } -#line 6658 "reflect.h2" +#line 6702 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10214,14 +10273,14 @@ size_t i{0}; return r; } -#line 6665 "reflect.h2" +#line 6709 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6673 "reflect.h2" +#line 6717 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10247,7 +10306,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6701 "reflect.h2" +#line 6745 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10273,11 +10332,11 @@ size_t i{0}; return r; } -#line 6738 "reflect.h2" +#line 6782 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6740 "reflect.h2" +#line 6784 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10351,7 +10410,7 @@ size_t i{0}; return nullptr; } -#line 6813 "reflect.h2" +#line 6857 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10364,7 +10423,7 @@ size_t i{0}; }} } -#line 6825 "reflect.h2" +#line 6869 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10378,7 +10437,7 @@ size_t i{0}; }} } -#line 6838 "reflect.h2" +#line 6882 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10398,7 +10457,7 @@ size_t i{0}; return r; } -#line 6857 "reflect.h2" +#line 6901 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10409,7 +10468,7 @@ size_t i{0}; return r; } -#line 6867 "reflect.h2" +#line 6911 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10421,14 +10480,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6878 "reflect.h2" +#line 6922 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6890 "reflect.h2" +#line 6934 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10452,7 +10511,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6914 "reflect.h2" +#line 6958 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10462,7 +10521,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6926 "reflect.h2" +#line 6970 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10478,7 +10537,7 @@ size_t i{0}; } } -#line 6946 "reflect.h2" +#line 6990 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10496,15 +10555,15 @@ size_t i{0}; }} } -#line 6982 "reflect.h2" +#line 7026 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 6985 "reflect.h2" +#line 7029 "reflect.h2" } -#line 6987 "reflect.h2" +#line 7031 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10540,7 +10599,7 @@ size_t i{0}; return source; } -#line 7022 "reflect.h2" +#line 7066 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10556,7 +10615,7 @@ size_t i{0}; } } -#line 7038 "reflect.h2" +#line 7082 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10565,7 +10624,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10620,7 +10679,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7107 "reflect.h2" +#line 7151 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10742,7 +10801,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7229 "reflect.h2" +#line 7273 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 9953fcbc5..a702ad748 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4005,6 +4005,21 @@ autodiff_context: type = { ); public suffix: std::string = "_d"; + private order: int = 1; + + // Members depending on order + public ad_type: std::string = "double"; + + set_order : (inout this, new_order: int) = { + order = new_order; + + if 1 == order { + ad_type = "double"; + } + else { + ad_type = "cpp2::taylor"; + } + } gen_temporary : (inout this) -> std::string = { temporary_count += 1; @@ -4014,9 +4029,11 @@ autodiff_context: type = { // TODO: Have the proper type declaration here. get_ad_type: (inout this, type: std::string) -> std::string = { - // TODO: Add type to required generation for AD. + if order == 1 { + return type; // Same type for now for order 1 + } - return type; // Use the same type for now. + return string_util::replace_all(type, "double", ad_type); } lookup_special_function_handling: (this, func_name: std::string, n_args: int, has_return: bool, is_member: bool) -> (m: bool, code: std::string) = { @@ -4032,6 +4049,13 @@ autodiff_context: type = { } } } + + enter_function: (inout this) = { + temporary_count = 0; + } + + leave_function: (inout this) = { + } } autodiff_handler_base: type = { @@ -4704,10 +4728,12 @@ autodiff: (inout t: meta::type_declaration) = { suffix_token : std::string_view == "suffix="; + order_token : std::string_view == "order="; args := t.get_arguments(); suffix : std::string = "_d"; + order : int = 1; for args do (arg_str) { if arg_str.starts_with("\"") && arg_str.ends_with("\"") { arg := arg_str.substr(1, arg_str.ssize() - 2); @@ -4716,18 +4742,31 @@ autodiff: (inout t: meta::type_declaration) = suffix = arg.substr(suffix_token.size()); continue; } + if arg.starts_with(order_token) { + if !string_util::string_to_int(arg.substr(order_token.size()), order) { + t.error("AD: Could not parse derivative order: (arg.substr(order_token.size()))$"); + return; + } + continue; + } } t.error("AD: Unknown argument: (arg_str)$"); return; } + ad_ctx: autodiff_context = (); + ad_ctx.suffix = suffix; + ad_ctx.set_order(order); + for t.get_members() do (m) if m.is_function() { mf := m.as_function(); + ad_ctx.enter_function(); + diff: std::string = " (mf.name())$(suffix)$: ("; // 1. Generate the modified signature @@ -4735,7 +4774,7 @@ autodiff: (inout t: meta::type_declaration) = for mf.get_parameters() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$, "; - diff += "(param.get_declaration().name())$(suffix)$ : (param.get_declaration().type())$, "; + diff += "(param.get_declaration().name())$(suffix)$ : (ad_ctx.get_ad_type(param.get_declaration().type()))$, "; } diff += ") -> ("; @@ -4755,7 +4794,7 @@ autodiff: (inout t: meta::type_declaration) = else { for mf.get_returns() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(param.get_declaration().name())$(suffix)$ : (param.get_declaration().type())$ = 0.0, "; + diff += "(param.get_declaration().name())$(suffix)$ : (ad_ctx.get_ad_type(param.get_declaration().type()))$ = 0.0, "; } } @@ -4768,8 +4807,7 @@ autodiff: (inout t: meta::type_declaration) = return; } - ad_ctx: autodiff_context = (); - ad_ctx.suffix = suffix; + ad_impl : autodiff_stmt_handler = (ad_ctx&, mf); @@ -4781,8 +4819,14 @@ autodiff: (inout t: meta::type_declaration) = diff += "}"; + ad_ctx.leave_function(); + t.add_member( diff ); } + + if 1 != order { + t.add_runtime_support_include( "cpp2taylor.h" ); + } } From 8b5c1e94b1eeb30314624e74b8d49b358c6e6391 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 13:30:11 +0200 Subject: [PATCH 24/54] Added handling for multiply and division. --- .../pure2-autodiff-higher-order.cpp2 | 42 +- .../pure2-autodiff-higher-order.cpp.execution | 56 + .../pure2-autodiff-higher-order.cpp | 205 +++- .../pure2-autodiff-higher-order.cpp2.output | 178 +++ source/reflect.h | 1074 +++++++++-------- source/reflect.h2 | 35 +- 6 files changed, 1032 insertions(+), 558 deletions(-) diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index fd4d72ac1..8fd5a58e3 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -23,6 +23,34 @@ ad_test: @autodiff<"order=6"> @print type = { add_sub_2: (x: double, y: double) -> (r: double) = { r = x + y - x; } + + mul_1: (x: double, y: double) -> (r: double) = { + r = x * y; + } + + mul_2: (x: double, y: double) -> (r: double) = { + r = x * y * x; + } + + div_1: (x: double, y: double) -> (r: double) = { + r = x / y; + } + + div_2: (x: double, y: double) -> (r: double) = { + r = x / y / y; + } + + mul_div_2: (x: double, y: double) -> (r: double) = { + r = x * y / x; + } + + mul_add: (x: double, y: double) -> (r: double) = { + r = x * (x + y); + } + + add_mul: (x: double, y: double) -> (r: double) = { + r = x + x * y; + } } write_output: (func: std::string, x: double, x_d: ad_type, y: double, y_d: ad_type, ret) = { @@ -47,13 +75,13 @@ main: () = { write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); -// write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); -// write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); -// write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); -// write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); -// write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); -// write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); -// write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); // write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); // write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); // write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index 32df76b0d..7231ee6a5 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -38,3 +38,59 @@ diff(x + y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0. d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 6.000000 + d1 = 7.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y * x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 12.000000 + d1 = 20.000000 + d2 = 22.000000 + d3 = 12.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.666667 + d1 = -0.111111 + d2 = 0.148148 + d3 = -0.296296 + d4 = 0.790123 + d5 = -2.633745 + d6 = 10.534979 +diff(x / y / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.222222 + d1 = -0.185185 + d2 = 0.296296 + d3 = -0.691358 + d4 = 2.106996 + d5 = -7.901235 + d6 = 35.116598 +diff(x * y / x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * (x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 8.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 7fdb306ad..d80c0c70e 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -47,6 +47,41 @@ using add_sub_2_ret = double; #line 23 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; +using mul_1_ret = double; + + +#line 27 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; +using mul_2_ret = double; + + +#line 31 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; +using div_1_ret = double; + + +#line 35 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; +using div_2_ret = double; + + +#line 39 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; +using mul_div_2_ret = double; + + +#line 43 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; +using mul_add_ret = double; + + +#line 47 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; +using add_mul_ret = double; + + +#line 51 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -68,17 +103,45 @@ struct add_sub_2_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto add_sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_sub_2_d_ret; +struct mul_1_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto mul_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_1_d_ret; + +struct mul_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto mul_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_2_d_ret; + +struct div_1_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto div_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_1_d_ret; + +struct div_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_2_d_ret; + +struct mul_div_2_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto mul_div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_div_2_d_ret; + +struct mul_add_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto mul_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_add_d_ret; + +struct add_mul_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 26 "pure2-autodiff-higher-order.cpp2" +#line 54 "pure2-autodiff-higher-order.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 37 "pure2-autodiff-higher-order.cpp2" +#line 65 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -120,6 +183,55 @@ auto main() -> int; r.construct(x + y - x); return std::move(r.value()); } +#line 27 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ + cpp2::impl::deferred_init r; +#line 28 "pure2-autodiff-higher-order.cpp2" + r.construct(x * y); + return std::move(r.value()); } + +#line 31 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ + cpp2::impl::deferred_init r; +#line 32 "pure2-autodiff-higher-order.cpp2" + r.construct(x * y * x); + return std::move(r.value()); } + +#line 35 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ + cpp2::impl::deferred_init r; +#line 36 "pure2-autodiff-higher-order.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); + return std::move(r.value()); } + +#line 39 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ + cpp2::impl::deferred_init r; +#line 40 "pure2-autodiff-higher-order.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); + return std::move(r.value()); } + +#line 43 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ + cpp2::impl::deferred_init r; +#line 44 "pure2-autodiff-higher-order.cpp2" + r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); + return std::move(r.value()); } + +#line 47 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ + cpp2::impl::deferred_init r; +#line 48 "pure2-autodiff-higher-order.cpp2" + r.construct(x * (x + y)); + return std::move(r.value()); } + +#line 51 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ + cpp2::impl::deferred_init r; +#line 52 "pure2-autodiff-higher-order.cpp2" + r.construct(x + x * y); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0};r_d = x_d + y_d; @@ -155,25 +267,88 @@ auto main() -> int; return { std::move(r), std::move(r_d) }; } -#line 28 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::mul_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_1_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = CPP2_UFCS(mul)(x_d, y_d, x, y); + r = x * y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::mul_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; +auto temp_1 {x * y}; r_d = CPP2_UFCS(mul)(cpp2::move(temp_1_d), x_d, temp_1, x); + r = cpp2::move(temp_1) * x; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::div_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_1_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = CPP2_UFCS(div)(x_d, y_d, x, y); + r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {CPP2_UFCS(div)(x_d, y_d, x, y)}; +auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), y_d, temp_1, y); + r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::mul_div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_div_2_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; +auto temp_1 {x * y}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), x_d, temp_1, x); + r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_add_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {x_d + y_d}; + + auto temp_1 {x + y}; + r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); + r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; + + auto temp_1 {x * y}; + r_d = x_d + cpp2::move(temp_1_d); + r = x + cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } + +#line 56 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 32 "pure2-autodiff-higher-order.cpp2" +#line 60 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 35 "pure2-autodiff-higher-order.cpp2" +#line 63 "pure2-autodiff-higher-order.cpp2" } -#line 37 "pure2-autodiff-higher-order.cpp2" +#line 65 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 40 "pure2-autodiff-higher-order.cpp2" +#line 68 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; @@ -183,14 +358,14 @@ auto main() -> int{ write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); -// write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); -// write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); -// write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); -// write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); -// write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); -// write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); -// write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); // write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); // write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); // write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 48eed81da..df1d345da 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -47,6 +47,69 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + mul_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y; + return; + } + + mul_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y * x; + return; + } + + div_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y; + return; + } + + div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y / y; + return; + } + + mul_div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y / x; + return; + } + + mul_add:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * (x + y); + return; + } + + add_mul:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + x * y; + return; + } + add_1_d:( in x: double, in x_d: cpp2::taylor, @@ -121,6 +184,121 @@ ad_test:/* @autodiff<"order=6"> @print */ type = r = x + y - x; return; } + + mul_1_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d.mul(y_d, x, y); + r = x * y; + return; + } + + mul_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d.mul(y_d, x, y); + temp_1: _ = x * y; + r_d = temp_1_d.mul(x_d, temp_1, x); + r = temp_1 * x; + return; + } + + div_1_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d.div(y_d, x, y); + r = x / y; + return; + } + + div_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d.div(y_d, x, y); + temp_1: _ = x / y; + r_d = temp_1_d.div(y_d, temp_1, y); + r = temp_1 / y; + return; + } + + mul_div_2_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d.mul(y_d, x, y); + temp_1: _ = x * y; + r_d = temp_1_d.div(x_d, temp_1, x); + r = temp_1 / x; + return; + } + + mul_add_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d + y_d; + temp_1: _ = x + y; + r_d = x_d.mul(temp_1_d, x, temp_1); + r = x * temp_1; + return; + } + + add_mul_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d.mul(y_d, x, y); + temp_1: _ = x * y; + r_d = x_d + temp_1_d; + r = x + temp_1; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/source/reflect.h b/source/reflect.h index 582893432..e503cc72f 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -115,88 +115,88 @@ class autodiff_special_func; class autodiff_context; -#line 4061 "reflect.h2" +#line 4063 "reflect.h2" class autodiff_handler_base; -#line 4075 "reflect.h2" +#line 4077 "reflect.h2" class autodiff_expression_handler; -#line 4468 "reflect.h2" +#line 4485 "reflect.h2" class autodiff_stmt_handler; -#line 4851 "reflect.h2" +#line 4868 "reflect.h2" class expression_flags; -#line 4867 "reflect.h2" +#line 4884 "reflect.h2" class regex_token; -#line 4894 "reflect.h2" +#line 4911 "reflect.h2" class regex_token_check; -#line 4915 "reflect.h2" +#line 4932 "reflect.h2" class regex_token_code; -#line 4936 "reflect.h2" +#line 4953 "reflect.h2" class regex_token_empty; -#line 4954 "reflect.h2" +#line 4971 "reflect.h2" class regex_token_list; -#line 5006 "reflect.h2" +#line 5023 "reflect.h2" class parse_context_group_state; -#line 5067 "reflect.h2" +#line 5084 "reflect.h2" class parse_context_branch_reset_state; -#line 5110 "reflect.h2" +#line 5127 "reflect.h2" class parse_context; -#line 5511 "reflect.h2" +#line 5528 "reflect.h2" class generation_function_context; -#line 5529 "reflect.h2" +#line 5546 "reflect.h2" class generation_context; -#line 5728 "reflect.h2" +#line 5745 "reflect.h2" class alternative_token; -#line 5743 "reflect.h2" +#line 5760 "reflect.h2" class alternative_token_gen; -#line 5808 "reflect.h2" +#line 5825 "reflect.h2" class any_token; -#line 5825 "reflect.h2" +#line 5842 "reflect.h2" class atomic_group_token; -#line 5855 "reflect.h2" +#line 5872 "reflect.h2" class char_token; -#line 5970 "reflect.h2" +#line 5987 "reflect.h2" class class_token; -#line 6194 "reflect.h2" +#line 6211 "reflect.h2" class group_ref_token; -#line 6331 "reflect.h2" +#line 6348 "reflect.h2" class group_token; -#line 6678 "reflect.h2" +#line 6695 "reflect.h2" class lookahead_lookbehind_token; -#line 6773 "reflect.h2" +#line 6790 "reflect.h2" class range_token; -#line 6930 "reflect.h2" +#line 6947 "reflect.h2" class special_range_token; -#line 7016 "reflect.h2" +#line 7033 "reflect.h2" template class regex_generator; -#line 7273 "reflect.h2" +#line 7290 "reflect.h2" } } @@ -1694,28 +1694,30 @@ class autodiff_context { public: auto set_order(cpp2::impl::in new_order) & -> void; #line 4024 "reflect.h2" + public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); + public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4030 "reflect.h2" +#line 4032 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4039 "reflect.h2" +#line 4041 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4053 "reflect.h2" +#line 4055 "reflect.h2" public: auto enter_function() & -> void; -#line 4057 "reflect.h2" +#line 4059 "reflect.h2" public: auto leave_function() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4059 "reflect.h2" +#line 4061 "reflect.h2" }; class autodiff_handler_base { @@ -1724,21 +1726,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4066 "reflect.h2" +#line 4068 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4070 "reflect.h2" +#line 4072 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4073 "reflect.h2" +#line 4075 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4079 "reflect.h2" +#line 4081 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1747,180 +1749,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4096 "reflect.h2" +#line 4098 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4115 "reflect.h2" +#line 4117 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4124 "reflect.h2" +#line 4126 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4162 "reflect.h2" +#line 4164 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4259 "reflect.h2" +#line 4261 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4292 "reflect.h2" +#line 4294 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4296 "reflect.h2" +#line 4298 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4300 "reflect.h2" +#line 4302 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4304 "reflect.h2" +#line 4306 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4308 "reflect.h2" +#line 4310 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4312 "reflect.h2" +#line 4314 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4316 "reflect.h2" +#line 4318 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4320 "reflect.h2" +#line 4322 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4324 "reflect.h2" +#line 4326 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4328 "reflect.h2" +#line 4330 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4332 "reflect.h2" +#line 4334 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4336 "reflect.h2" +#line 4338 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4359 "reflect.h2" +#line 4362 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4402 "reflect.h2" +#line 4419 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4406 "reflect.h2" +#line 4423 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4411 "reflect.h2" +#line 4428 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4438 "reflect.h2" +#line 4455 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4466 "reflect.h2" +#line 4483 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4472 "reflect.h2" +#line 4489 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4481 "reflect.h2" +#line 4498 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4486 "reflect.h2" +#line 4503 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4491 "reflect.h2" +#line 4508 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4509 "reflect.h2" +#line 4526 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4514 "reflect.h2" +#line 4531 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4519 "reflect.h2" +#line 4536 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4524 "reflect.h2" +#line 4541 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4532 "reflect.h2" +#line 4549 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4548 "reflect.h2" +#line 4565 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4595 "reflect.h2" +#line 4612 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4606 "reflect.h2" +#line 4623 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4634 "reflect.h2" +#line 4651 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4639 "reflect.h2" +#line 4656 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4643 "reflect.h2" +#line 4660 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4647 "reflect.h2" +#line 4664 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4651 "reflect.h2" +#line 4668 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4655 "reflect.h2" +#line 4672 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4659 "reflect.h2" +#line 4676 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4663 "reflect.h2" +#line 4680 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4667 "reflect.h2" +#line 4684 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4671 "reflect.h2" +#line 4688 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4675 "reflect.h2" +#line 4692 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4679 "reflect.h2" +#line 4696 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4683 "reflect.h2" +#line 4700 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4687 "reflect.h2" +#line 4704 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4692 "reflect.h2" +#line 4709 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4721 "reflect.h2" +#line 4738 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4725 "reflect.h2" +#line 4742 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4847 "reflect.h2" +#line 4864 "reflect.h2" using error_func = std::function x)>; -#line 4851 "reflect.h2" +#line 4868 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1955,20 +1957,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4859 "reflect.h2" +#line 4876 "reflect.h2" }; -#line 4867 "reflect.h2" +#line 4884 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4875 "reflect.h2" +#line 4892 "reflect.h2" public: explicit regex_token(); -#line 4880 "reflect.h2" +#line 4897 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1980,103 +1982,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4886 "reflect.h2" +#line 4903 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4892 "reflect.h2" +#line 4909 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4898 "reflect.h2" +#line 4915 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4905 "reflect.h2" +#line 4922 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4909 "reflect.h2" +#line 4926 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4910 "reflect.h2" +#line 4927 "reflect.h2" }; -#line 4913 "reflect.h2" +#line 4930 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4919 "reflect.h2" +#line 4936 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4926 "reflect.h2" +#line 4943 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4930 "reflect.h2" +#line 4947 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4931 "reflect.h2" +#line 4948 "reflect.h2" }; -#line 4934 "reflect.h2" +#line 4951 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4940 "reflect.h2" +#line 4957 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4944 "reflect.h2" +#line 4961 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4948 "reflect.h2" +#line 4965 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4949 "reflect.h2" +#line 4966 "reflect.h2" }; -#line 4952 "reflect.h2" +#line 4969 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4958 "reflect.h2" +#line 4975 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4965 "reflect.h2" +#line 4982 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4971 "reflect.h2" +#line 4988 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4977 "reflect.h2" +#line 4994 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 4985 "reflect.h2" +#line 5002 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2084,10 +2086,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 4997 "reflect.h2" +#line 5014 "reflect.h2" }; -#line 5000 "reflect.h2" +#line 5017 "reflect.h2" // // Parse and generation context. // @@ -2103,33 +2105,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5020 "reflect.h2" +#line 5037 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5027 "reflect.h2" +#line 5044 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5039 "reflect.h2" +#line 5056 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5044 "reflect.h2" +#line 5061 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5048 "reflect.h2" +#line 5065 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5062 "reflect.h2" +#line 5079 "reflect.h2" }; -#line 5065 "reflect.h2" +#line 5082 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2142,25 +2144,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5083 "reflect.h2" +#line 5100 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5089 "reflect.h2" +#line 5106 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5096 "reflect.h2" +#line 5113 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5103 "reflect.h2" +#line 5120 "reflect.h2" }; -#line 5106 "reflect.h2" +#line 5123 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2176,7 +2178,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5122 "reflect.h2" +#line 5139 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2184,64 +2186,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5133 "reflect.h2" +#line 5150 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5146 "reflect.h2" +#line 5163 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5154 "reflect.h2" +#line 5171 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5158 "reflect.h2" +#line 5175 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5162 "reflect.h2" +#line 5179 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5174 "reflect.h2" +#line 5191 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5181 "reflect.h2" +#line 5198 "reflect.h2" public: auto next_alternative() & -> void; -#line 5187 "reflect.h2" +#line 5204 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5193 "reflect.h2" +#line 5210 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5197 "reflect.h2" +#line 5214 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5208 "reflect.h2" +#line 5225 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5212 "reflect.h2" +#line 5229 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5218 "reflect.h2" +#line 5235 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5222 "reflect.h2" +#line 5239 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5229 "reflect.h2" +#line 5246 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5240 "reflect.h2" +#line 5257 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2249,51 +2251,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5284 "reflect.h2" +#line 5301 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5296 "reflect.h2" +#line 5313 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5309 "reflect.h2" +#line 5326 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5332 "reflect.h2" +#line 5349 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5349 "reflect.h2" +#line 5366 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5370 "reflect.h2" +#line 5387 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5380 "reflect.h2" +#line 5397 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5384 "reflect.h2" +#line 5401 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5440 "reflect.h2" +#line 5457 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5479 "reflect.h2" +#line 5496 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5494 "reflect.h2" +#line 5511 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2305,10 +2307,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5505 "reflect.h2" +#line 5522 "reflect.h2" }; -#line 5508 "reflect.h2" +#line 5525 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2318,16 +2320,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5522 "reflect.h2" +#line 5539 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5525 "reflect.h2" +#line 5542 "reflect.h2" }; -#line 5528 "reflect.h2" +#line 5545 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2347,68 +2349,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5550 "reflect.h2" +#line 5567 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5556 "reflect.h2" +#line 5573 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5565 "reflect.h2" +#line 5582 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5576 "reflect.h2" +#line 5593 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5583 "reflect.h2" +#line 5600 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5603 "reflect.h2" +#line 5620 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5613 "reflect.h2" +#line 5630 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5636 "reflect.h2" +#line 5653 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5644 "reflect.h2" +#line 5661 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5648 "reflect.h2" +#line 5665 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5654 "reflect.h2" +#line 5671 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5660 "reflect.h2" +#line 5677 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5670 "reflect.h2" +#line 5687 "reflect.h2" public: auto finish_context() & -> void; -#line 5678 "reflect.h2" +#line 5695 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5684 "reflect.h2" +#line 5701 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5688 "reflect.h2" +#line 5705 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5692 "reflect.h2" +#line 5709 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5716 "reflect.h2" +#line 5733 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2416,7 +2418,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5722 "reflect.h2" +#line 5739 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2436,27 +2438,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5741 "reflect.h2" +#line 5758 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5747 "reflect.h2" +#line 5764 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5754 "reflect.h2" +#line 5771 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5771 "reflect.h2" +#line 5788 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5778 "reflect.h2" +#line 5795 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5791 "reflect.h2" +#line 5808 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2464,19 +2466,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5803 "reflect.h2" +#line 5820 "reflect.h2" }; -#line 5806 "reflect.h2" +#line 5823 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5812 "reflect.h2" +#line 5829 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5816 "reflect.h2" +#line 5833 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2484,7 +2486,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5821 "reflect.h2" +#line 5838 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2492,17 +2494,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5829 "reflect.h2" +#line 5846 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5840 "reflect.h2" +#line 5857 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5848 "reflect.h2" +#line 5865 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2510,7 +2512,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5851 "reflect.h2" +#line 5868 "reflect.h2" }; // Regex syntax: a @@ -2518,34 +2520,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5859 "reflect.h2" +#line 5876 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5868 "reflect.h2" +#line 5885 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5874 "reflect.h2" +#line 5891 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5878 "reflect.h2" +#line 5895 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5901 "reflect.h2" +#line 5918 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5922 "reflect.h2" +#line 5939 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5940 "reflect.h2" +#line 5957 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5955 "reflect.h2" +#line 5972 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5961 "reflect.h2" +#line 5978 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2553,33 +2555,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5965 "reflect.h2" +#line 5982 "reflect.h2" }; -#line 5968 "reflect.h2" +#line 5985 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5974 "reflect.h2" +#line 5991 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 5986 "reflect.h2" +#line 6003 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6112 "reflect.h2" +#line 6129 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6121 "reflect.h2" +#line 6138 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6126 "reflect.h2" +#line 6143 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2587,20 +2589,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6133 "reflect.h2" +#line 6150 "reflect.h2" }; -#line 6136 "reflect.h2" +#line 6153 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6177 "reflect.h2" +#line 6194 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6188 "reflect.h2" +#line 6205 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2610,20 +2612,20 @@ class class_token class group_ref_token : public regex_token { -#line 6198 "reflect.h2" +#line 6215 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6210 "reflect.h2" +#line 6227 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6311 "reflect.h2" +#line 6328 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6315 "reflect.h2" +#line 6332 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2631,10 +2633,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6318 "reflect.h2" +#line 6335 "reflect.h2" }; -#line 6321 "reflect.h2" +#line 6338 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2648,29 +2650,29 @@ class group_ref_token class group_token : public regex_token { -#line 6335 "reflect.h2" +#line 6352 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6357 "reflect.h2" +#line 6374 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6371 "reflect.h2" +#line 6388 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6530 "reflect.h2" +#line 6547 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6538 "reflect.h2" +#line 6555 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6556 "reflect.h2" +#line 6573 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6587 "reflect.h2" +#line 6604 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2679,25 +2681,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6594 "reflect.h2" +#line 6611 "reflect.h2" }; -#line 6597 "reflect.h2" +#line 6614 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6638 "reflect.h2" +#line 6655 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6658 "reflect.h2" +#line 6675 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6674 "reflect.h2" +#line 6691 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2705,20 +2707,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6682 "reflect.h2" +#line 6699 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6691 "reflect.h2" +#line 6708 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6702 "reflect.h2" +#line 6719 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6709 "reflect.h2" +#line 6726 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2726,26 +2728,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6712 "reflect.h2" +#line 6729 "reflect.h2" }; -#line 6715 "reflect.h2" +#line 6732 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6743 "reflect.h2" +#line 6760 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6771 "reflect.h2" +#line 6788 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6777 "reflect.h2" +#line 6794 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2755,22 +2757,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6857 "reflect.h2" +#line 6874 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6869 "reflect.h2" +#line 6886 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6882 "reflect.h2" +#line 6899 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6901 "reflect.h2" +#line 6918 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6911 "reflect.h2" +#line 6928 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6922 "reflect.h2" +#line 6939 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2778,16 +2780,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6925 "reflect.h2" +#line 6942 "reflect.h2" }; -#line 6928 "reflect.h2" +#line 6945 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6934 "reflect.h2" +#line 6951 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2796,7 +2798,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6964 "reflect.h2" +#line 6981 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2805,14 +2807,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 6986 "reflect.h2" +#line 7003 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7008 "reflect.h2" +#line 7025 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2833,24 +2835,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7031 "reflect.h2" +#line 7048 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7066 "reflect.h2" +#line 7083 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7080 "reflect.h2" +#line 7097 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7092 "reflect.h2" +#line 7109 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7147 "reflect.h2" +#line 7164 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2861,7 +2863,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7273 "reflect.h2" +#line 7290 "reflect.h2" } } @@ -7502,13 +7504,16 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } #line 4024 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } + +#line 4026 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4030 "reflect.h2" +#line 4032 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ if (order == 1) { @@ -7518,11 +7523,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return string_util::replace_all(type, "double", ad_type); } -#line 4039 "reflect.h2" +#line 4041 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4040 "reflect.h2" +#line 4042 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7536,36 +7541,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return { std::move(m.value()), std::move(code.value()) }; } -#line 4053 "reflect.h2" +#line 4055 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4057 "reflect.h2" +#line 4059 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4066 "reflect.h2" +#line 4068 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4068 "reflect.h2" +#line 4070 "reflect.h2" } -#line 4066 "reflect.h2" +#line 4068 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4068 "reflect.h2" +#line 4070 "reflect.h2" } -#line 4070 "reflect.h2" +#line 4072 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4085 "reflect.h2" +#line 4087 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7573,13 +7578,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4091 "reflect.h2" +#line 4093 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4096 "reflect.h2" +#line 4098 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7599,7 +7604,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4115 "reflect.h2" +#line 4117 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7609,7 +7614,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4124 "reflect.h2" +#line 4126 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7648,7 +7653,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4162 "reflect.h2" +#line 4164 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7656,7 +7661,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4168 "reflect.h2" +#line 4170 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7670,7 +7675,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4180 "reflect.h2" +#line 4182 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7693,7 +7698,7 @@ auto i{0}; { auto i{0}; -#line 4201 "reflect.h2" +#line 4203 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7718,7 +7723,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4224 "reflect.h2" +#line 4226 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7754,7 +7759,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation. } -#line 4259 "reflect.h2" +#line 4261 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7779,75 +7784,75 @@ auto i{0}; { auto i{1}; -#line 4282 "reflect.h2" +#line 4284 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4287 "reflect.h2" +#line 4289 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4292 "reflect.h2" +#line 4294 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4296 "reflect.h2" +#line 4298 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4300 "reflect.h2" +#line 4302 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4304 "reflect.h2" +#line 4306 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4308 "reflect.h2" +#line 4310 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4312 "reflect.h2" +#line 4314 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4316 "reflect.h2" +#line 4318 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4320 "reflect.h2" +#line 4322 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4324 "reflect.h2" +#line 4326 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4328 "reflect.h2" +#line 4330 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4332 "reflect.h2" +#line 4334 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4336 "reflect.h2" +#line 4338 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7862,7 +7867,8 @@ auto i{1}; } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; - fwd += "" + cpp2::to_string(var) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""; + auto var_d {var + (*cpp2::impl::assert_not_null(ctx)).suffix}; + fwd += "" + cpp2::to_string(cpp2::move(var_d)) + ""; primal += "" + cpp2::to_string(cpp2::move(var)) + ""; first = false; @@ -7871,15 +7877,17 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4359 "reflect.h2" +#line 4362 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto arg_a {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; + auto arg_a_d {arg_a + (*cpp2::impl::assert_not_null(ctx)).suffix}; int i {1}; for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(terms)); i += 1 ) { auto arg_b {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; + auto arg_b_d {arg_b + (*cpp2::impl::assert_not_null(ctx)).suffix}; auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; @@ -7887,18 +7895,28 @@ auto i{1}; std::string primal {""}; if ("*" == op) { - fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""; + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + fwd = "" + cpp2::to_string(arg_a_d) + ".mul(" + cpp2::to_string(cpp2::move(arg_b_d)) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + } + else { + fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a_d) + ""; + } primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; } else {if ("/" == op) { - fwd = "" + cpp2::to_string(arg_a) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(arg_b) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + fwd = "" + cpp2::to_string(arg_a_d) + ".div(" + cpp2::to_string(cpp2::move(arg_b_d)) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + } + else { + fwd = "" + cpp2::to_string(arg_a_d) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + } primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; } else { CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4386 "reflect.h2" +#line 4401 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7906,27 +7924,29 @@ auto i{1}; else { // Temporary auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).suffix}; // TODO: Get type of expression, in order to define the type of t. - diff += "" + cpp2::to_string(t) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " := " + cpp2::to_string(cpp2::move(fwd)) + ";"; + diff += "" + cpp2::to_string(t_d) + " := " + cpp2::to_string(cpp2::move(fwd)) + ";"; diff += "" + cpp2::to_string(t) + " := " + cpp2::to_string(cpp2::move(primal)) + ";"; - arg_a = cpp2::move(t); + arg_a = cpp2::move(t); + arg_a_d = cpp2::move(t_d); } } } -#line 4402 "reflect.h2" +#line 4419 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4406 "reflect.h2" +#line 4423 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4411 "reflect.h2" +#line 4428 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7935,7 +7955,7 @@ auto i{1}; { auto i{0}; -#line 4418 "reflect.h2" +#line 4435 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7949,7 +7969,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4430 "reflect.h2" +#line 4447 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7958,7 +7978,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4438 "reflect.h2" +#line 4455 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7988,26 +8008,26 @@ auto i{0}; }}}} } -#line 4476 "reflect.h2" +#line 4493 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4479 "reflect.h2" +#line 4496 "reflect.h2" } -#line 4481 "reflect.h2" +#line 4498 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4486 "reflect.h2" +#line 4503 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4491 "reflect.h2" +#line 4508 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8025,22 +8045,22 @@ auto i{0}; } } -#line 4509 "reflect.h2" +#line 4526 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4514 "reflect.h2" +#line 4531 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4519 "reflect.h2" +#line 4536 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4524 "reflect.h2" +#line 4541 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8048,7 +8068,7 @@ auto i{0}; diff += "}\n"; } -#line 4532 "reflect.h2" +#line 4549 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8064,7 +8084,7 @@ auto i{0}; } } -#line 4548 "reflect.h2" +#line 4565 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8111,7 +8131,7 @@ auto i{0}; }} } -#line 4595 "reflect.h2" +#line 4612 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8123,7 +8143,7 @@ auto i{0}; } } -#line 4606 "reflect.h2" +#line 4623 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8152,79 +8172,79 @@ auto i{0}; } } -#line 4634 "reflect.h2" +#line 4651 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4639 "reflect.h2" +#line 4656 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4643 "reflect.h2" +#line 4660 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4647 "reflect.h2" +#line 4664 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4651 "reflect.h2" +#line 4668 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4655 "reflect.h2" +#line 4672 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4659 "reflect.h2" +#line 4676 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4663 "reflect.h2" +#line 4680 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4667 "reflect.h2" +#line 4684 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4671 "reflect.h2" +#line 4688 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4675 "reflect.h2" +#line 4692 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4679 "reflect.h2" +#line 4696 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4683 "reflect.h2" +#line 4700 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4687 "reflect.h2" +#line 4704 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4692 "reflect.h2" +#line 4709 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8233,7 +8253,7 @@ auto i{0}; { auto i{0}; -#line 4699 "reflect.h2" +#line 4716 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8247,7 +8267,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4711 "reflect.h2" +#line 4728 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8258,13 +8278,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4721 "reflect.h2" +#line 4738 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4727 "reflect.h2" +#line 4744 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8348,10 +8368,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } -#line 4811 "reflect.h2" +#line 4828 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4814 "reflect.h2" +#line 4831 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8461,7 +8481,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4833 "reflect.h2" +#line 4850 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8477,11 +8497,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4849 "reflect.h2" +#line 4866 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4853 "reflect.h2" +#line 4870 "reflect.h2" // mod: i // mod: m // mod: s @@ -8489,116 +8509,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4862 "reflect.h2" +#line 4879 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4871 "reflect.h2" +#line 4888 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4873 "reflect.h2" +#line 4890 "reflect.h2" } -#line 4875 "reflect.h2" +#line 4892 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4877 "reflect.h2" +#line 4894 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4883 "reflect.h2" +#line 4900 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4884 "reflect.h2" +#line 4901 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4885 "reflect.h2" +#line 4902 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4900 "reflect.h2" +#line 4917 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4903 "reflect.h2" +#line 4920 "reflect.h2" } -#line 4905 "reflect.h2" +#line 4922 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4909 "reflect.h2" +#line 4926 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4921 "reflect.h2" +#line 4938 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4924 "reflect.h2" +#line 4941 "reflect.h2" } -#line 4926 "reflect.h2" +#line 4943 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4930 "reflect.h2" +#line 4947 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4940 "reflect.h2" +#line 4957 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4942 "reflect.h2" +#line 4959 "reflect.h2" } -#line 4944 "reflect.h2" +#line 4961 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4948 "reflect.h2" +#line 4965 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4960 "reflect.h2" +#line 4977 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4963 "reflect.h2" +#line 4980 "reflect.h2" } -#line 4965 "reflect.h2" +#line 4982 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4971 "reflect.h2" +#line 4988 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4977 "reflect.h2" +#line 4994 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8607,7 +8627,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 4985 "reflect.h2" +#line 5002 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8623,7 +8643,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5013 "reflect.h2" +#line 5030 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8631,14 +8651,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5021 "reflect.h2" +#line 5038 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5028 "reflect.h2" +#line 5045 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8650,15 +8670,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5040 "reflect.h2" +#line 5057 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5045 "reflect.h2" +#line 5062 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5049 "reflect.h2" +#line 5066 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8679,7 +8699,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5075 "reflect.h2" +#line 5092 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8688,20 +8708,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5084 "reflect.h2" +#line 5101 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5090 "reflect.h2" +#line 5107 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5097 "reflect.h2" +#line 5114 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8716,16 +8736,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5127 "reflect.h2" +#line 5144 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5131 "reflect.h2" +#line 5148 "reflect.h2" } -#line 5137 "reflect.h2" +#line 5154 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8735,7 +8755,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5147 "reflect.h2" +#line 5164 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8743,17 +8763,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5154 "reflect.h2" +#line 5171 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5158 "reflect.h2" +#line 5175 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5165 "reflect.h2" +#line 5182 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8763,7 +8783,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5174 "reflect.h2" +#line 5191 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8771,24 +8791,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5181 "reflect.h2" +#line 5198 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5189 "reflect.h2" +#line 5206 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5193 "reflect.h2" +#line 5210 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5197 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8800,22 +8820,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5208 "reflect.h2" +#line 5225 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5214 "reflect.h2" +#line 5231 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5218 "reflect.h2" +#line 5235 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5222 "reflect.h2" +#line 5239 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8823,7 +8843,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5229 "reflect.h2" +#line 5246 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8835,10 +8855,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5242 "reflect.h2" +#line 5259 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5245 "reflect.h2" +#line 5262 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8878,7 +8898,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5285 "reflect.h2" +#line 5302 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8890,14 +8910,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5296 "reflect.h2" +#line 5313 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5297 "reflect.h2" +#line 5314 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5298 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5300 "reflect.h2" +#line 5317 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8907,10 +8927,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5309 "reflect.h2" +#line 5326 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5311 "reflect.h2" +#line 5328 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8932,14 +8952,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5332 "reflect.h2" +#line 5349 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5333 "reflect.h2" +#line 5350 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5334 "reflect.h2" +#line 5351 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5336 "reflect.h2" +#line 5353 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8953,7 +8973,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5349 "reflect.h2" +#line 5366 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8975,7 +8995,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5370 "reflect.h2" +#line 5387 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -8986,12 +9006,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5380 "reflect.h2" +#line 5397 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5381 "reflect.h2" +#line 5398 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5386 "reflect.h2" +#line 5403 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9046,7 +9066,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5440 "reflect.h2" +#line 5457 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9086,7 +9106,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5479 "reflect.h2" +#line 5496 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9102,21 +9122,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5496 "reflect.h2" +#line 5513 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5497 "reflect.h2" +#line 5514 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5498 "reflect.h2" +#line 5515 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5500 "reflect.h2" +#line 5517 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5515 "reflect.h2" +#line 5532 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9124,7 +9144,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5522 "reflect.h2" +#line 5539 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9134,22 +9154,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5540 "reflect.h2" +#line 5557 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5545 "reflect.h2" +#line 5562 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5551 "reflect.h2" +#line 5568 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5557 "reflect.h2" +#line 5574 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9158,7 +9178,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5565 "reflect.h2" +#line 5582 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9170,7 +9190,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5576 "reflect.h2" +#line 5593 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9178,7 +9198,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5583 "reflect.h2" +#line 5600 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9199,7 +9219,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5604 "reflect.h2" +#line 5621 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9209,7 +9229,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5614 "reflect.h2" +#line 5631 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9232,33 +9252,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5638 "reflect.h2" +#line 5655 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5644 "reflect.h2" +#line 5661 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5648 "reflect.h2" +#line 5665 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5654 "reflect.h2" +#line 5671 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5662 "reflect.h2" +#line 5679 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9267,7 +9287,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5670 "reflect.h2" +#line 5687 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9276,22 +9296,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5680 "reflect.h2" +#line 5697 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5684 "reflect.h2" +#line 5701 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5688 "reflect.h2" +#line 5705 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5692 "reflect.h2" +#line 5709 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9315,18 +9335,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5717 "reflect.h2" +#line 5734 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5732 "reflect.h2" +#line 5749 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5734 "reflect.h2" +#line 5751 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9337,15 +9357,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5749 "reflect.h2" +#line 5766 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5752 "reflect.h2" +#line 5769 "reflect.h2" } -#line 5754 "reflect.h2" +#line 5771 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9363,7 +9383,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5771 "reflect.h2" +#line 5788 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9371,7 +9391,7 @@ generation_function_context::generation_function_context(){} } } -#line 5778 "reflect.h2" +#line 5795 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9385,7 +9405,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5791 "reflect.h2" +#line 5808 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9401,14 +9421,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5812 "reflect.h2" +#line 5829 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5814 "reflect.h2" +#line 5831 "reflect.h2" } -#line 5816 "reflect.h2" +#line 5833 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9417,11 +9437,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5831 "reflect.h2" +#line 5848 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5833 "reflect.h2" +#line 5850 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9429,7 +9449,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5840 "reflect.h2" +#line 5857 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9438,37 +9458,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5848 "reflect.h2" +#line 5865 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5862 "reflect.h2" +#line 5879 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5866 "reflect.h2" +#line 5883 "reflect.h2" } -#line 5868 "reflect.h2" +#line 5885 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5872 "reflect.h2" +#line 5889 "reflect.h2" } -#line 5874 "reflect.h2" +#line 5891 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5878 "reflect.h2" +#line 5895 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9477,14 +9497,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5884 "reflect.h2" +#line 5901 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5889 "reflect.h2" +#line 5906 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9497,7 +9517,7 @@ size_t i{0}; } } -#line 5901 "reflect.h2" +#line 5918 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9519,7 +9539,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5922 "reflect.h2" +#line 5939 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9538,7 +9558,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5940 "reflect.h2" +#line 5957 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9554,14 +9574,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5955 "reflect.h2" +#line 5972 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5961 "reflect.h2" +#line 5978 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9569,19 +9589,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5978 "reflect.h2" +#line 5995 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5979 "reflect.h2" +#line 5996 "reflect.h2" { -#line 5984 "reflect.h2" +#line 6001 "reflect.h2" } -#line 5987 "reflect.h2" +#line 6004 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9707,7 +9727,7 @@ size_t i{0}; ); } -#line 6112 "reflect.h2" +#line 6129 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9717,13 +9737,13 @@ size_t i{0}; ); } -#line 6121 "reflect.h2" +#line 6138 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6126 "reflect.h2" +#line 6143 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9734,12 +9754,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6138 "reflect.h2" +#line 6155 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6143 "reflect.h2" +#line 6160 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9773,7 +9793,7 @@ size_t i{0}; } -#line 6179 "reflect.h2" +#line 6196 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9782,19 +9802,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6202 "reflect.h2" +#line 6219 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6203 "reflect.h2" +#line 6220 "reflect.h2" { -#line 6208 "reflect.h2" +#line 6225 "reflect.h2" } -#line 6210 "reflect.h2" +#line 6227 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9896,19 +9916,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6311 "reflect.h2" +#line 6328 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6315 "reflect.h2" +#line 6332 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6339 "reflect.h2" +#line 6356 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9927,7 +9947,7 @@ size_t i{0}; return r; } -#line 6357 "reflect.h2" +#line 6374 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9942,7 +9962,7 @@ size_t i{0}; return r; } -#line 6371 "reflect.h2" +#line 6388 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10102,7 +10122,7 @@ size_t i{0}; } } -#line 6530 "reflect.h2" +#line 6547 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10111,7 +10131,7 @@ size_t i{0}; return r; } -#line 6538 "reflect.h2" +#line 6555 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10130,7 +10150,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6556 "reflect.h2" +#line 6573 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10162,7 +10182,7 @@ size_t i{0}; } } -#line 6587 "reflect.h2" +#line 6604 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10173,7 +10193,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6599 "reflect.h2" +#line 6616 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10212,7 +10232,7 @@ size_t i{0}; return r; } -#line 6640 "reflect.h2" +#line 6657 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10230,7 +10250,7 @@ size_t i{0}; }} } -#line 6660 "reflect.h2" +#line 6677 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10244,16 +10264,16 @@ size_t i{0}; } } -#line 6686 "reflect.h2" +#line 6703 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6689 "reflect.h2" +#line 6706 "reflect.h2" } -#line 6691 "reflect.h2" +#line 6708 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10265,7 +10285,7 @@ size_t i{0}; } } -#line 6702 "reflect.h2" +#line 6719 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10273,14 +10293,14 @@ size_t i{0}; return r; } -#line 6709 "reflect.h2" +#line 6726 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6717 "reflect.h2" +#line 6734 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10306,7 +10326,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6745 "reflect.h2" +#line 6762 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10332,11 +10352,11 @@ size_t i{0}; return r; } -#line 6782 "reflect.h2" +#line 6799 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6784 "reflect.h2" +#line 6801 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10410,7 +10430,7 @@ size_t i{0}; return nullptr; } -#line 6857 "reflect.h2" +#line 6874 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10423,7 +10443,7 @@ size_t i{0}; }} } -#line 6869 "reflect.h2" +#line 6886 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10437,7 +10457,7 @@ size_t i{0}; }} } -#line 6882 "reflect.h2" +#line 6899 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10457,7 +10477,7 @@ size_t i{0}; return r; } -#line 6901 "reflect.h2" +#line 6918 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10468,7 +10488,7 @@ size_t i{0}; return r; } -#line 6911 "reflect.h2" +#line 6928 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10480,14 +10500,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6922 "reflect.h2" +#line 6939 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6934 "reflect.h2" +#line 6951 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10511,7 +10531,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6958 "reflect.h2" +#line 6975 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10521,7 +10541,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6970 "reflect.h2" +#line 6987 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10537,7 +10557,7 @@ size_t i{0}; } } -#line 6990 "reflect.h2" +#line 7007 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10555,15 +10575,15 @@ size_t i{0}; }} } -#line 7026 "reflect.h2" +#line 7043 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7029 "reflect.h2" +#line 7046 "reflect.h2" } -#line 7031 "reflect.h2" +#line 7048 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10599,7 +10619,7 @@ size_t i{0}; return source; } -#line 7066 "reflect.h2" +#line 7083 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10615,7 +10635,7 @@ size_t i{0}; } } -#line 7082 "reflect.h2" +#line 7099 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10624,7 +10644,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10679,7 +10699,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7151 "reflect.h2" +#line 7168 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10801,7 +10821,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7273 "reflect.h2" +#line 7290 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index a702ad748..fc953d5b8 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4021,6 +4021,8 @@ autodiff_context: type = { } } + is_taylor: (this) = order != 1; + gen_temporary : (inout this) -> std::string = { temporary_count += 1; return "temp_(temporary_count)$"; @@ -4346,8 +4348,9 @@ autodiff_expression_handler: type = { primal += " (op)$ "; } - var := handle_expression_term(term.get_term()); - fwd += "(var)$(ctx*.suffix)$"; + var := handle_expression_term(term.get_term()); + var_d := var + ctx*.suffix; + fwd += "(var_d)$"; primal += "(var)$"; first = false; @@ -4359,11 +4362,13 @@ autodiff_expression_handler: type = { traverse: (override inout this, binexpr: meta::multiplicative_expression) = { terms := binexpr.get_terms(); - arg_a := handle_expression_term(terms[0].get_term()); + arg_a := handle_expression_term(terms[0].get_term()); + arg_a_d := arg_a + ctx*.suffix; i : int = 1; while i < terms.ssize() next i += 1 { - arg_b := handle_expression_term(terms[i].get_term()); + arg_b := handle_expression_term(terms[i].get_term()); + arg_b_d := arg_b + ctx*.suffix; op := terms[i].get_op().to_string(); @@ -4371,11 +4376,21 @@ autodiff_expression_handler: type = { primal : std::string = ""; if "*" == op { - fwd = "(arg_a)$ * (arg_b)$(ctx*.suffix)$ + (arg_b)$ * (arg_a)$(ctx*.suffix)$"; + if ctx*.is_taylor() { + fwd = "(arg_a_d)$.mul((arg_b_d)$, (arg_a)$, (arg_b)$)"; + } + else { + fwd = "(arg_a)$ * (arg_b_d)$ + (arg_b)$ * (arg_a_d)$"; + } primal = "(arg_a)$ * (arg_b)$"; } else if "/" == op { - fwd = "(arg_a)$(ctx*.suffix)$ / (arg_b)$ - (arg_a)$ * (arg_b)$(ctx*.suffix)$ / ((arg_b)$ * (arg_b)$)"; + if ctx*.is_taylor() { + fwd = "(arg_a_d)$.div((arg_b_d)$, (arg_a)$, (arg_b)$)"; + } + else { + fwd = "(arg_a_d)$ / (arg_b)$ - (arg_a)$ * (arg_b_d)$ / ((arg_b)$ * (arg_b)$)"; + } primal = "(arg_a)$ / (arg_b)$"; } else { @@ -4389,12 +4404,14 @@ autodiff_expression_handler: type = { } else { // Temporary - t := ctx*.gen_temporary(); + t := ctx*.gen_temporary(); + t_d := t + ctx*.suffix; // TODO: Get type of expression, in order to define the type of t. - diff += "(t)$(ctx*.suffix)$ := (fwd)$;"; + diff += "(t_d)$ := (fwd)$;"; diff += "(t)$ := (primal)$;"; - arg_a = t; + arg_a = t; + arg_a_d = t_d; } } } From 05cff2900ab8328e02cd73f520b793918c10dab0 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 13:49:27 +0200 Subject: [PATCH 25/54] Higher order handling for special functions. --- .../pure2-autodiff-higher-order.cpp2 | 16 +- regression-tests/pure2-autodiff.cpp2 | 2 +- .../pure2-autodiff-higher-order.cpp.execution | 16 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 +- .../pure2-autodiff-higher-order.cpp | 99 +- .../pure2-autodiff-higher-order.cpp2.output | 77 ++ .../test-results/pure2-autodiff.cpp | 2 +- source/reflect.h | 1130 +++++++++-------- source/reflect.h2 | 41 +- 9 files changed, 805 insertions(+), 580 deletions(-) diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index 8fd5a58e3..1d700a1f1 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -51,6 +51,18 @@ ad_test: @autodiff<"order=6"> @print type = { add_mul: (x: double, y: double) -> (r: double) = { r = x + x * y; } + + func: (x: double, y: double) -> (r: double) = { + r = x + y; + } + + func_call: (x: double, y: double) -> (r: double) = { + r = x * func(x, y); + } + + sin_call: (x: double, y: double) -> (r: double) = { + r = sin(x - y); + } } write_output: (func: std::string, x: double, x_d: ad_type, y: double, y_d: ad_type, ret) = { @@ -82,8 +94,8 @@ main: () = { write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); -// write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); -// write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); // write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); // write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); // write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index db1c354fa..1b78c2c2d 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -182,7 +182,7 @@ main: () = { write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index 7231ee6a5..4b430cd55 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -94,3 +94,19 @@ diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0. d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -0.841471 + d1 = -0.540302 + d2 = 0.841471 + d3 = 0.540302 + d4 = -0.841471 + d5 = -0.540302 + d6 = 0.841471 diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index f9c2c2a00..278b7af31 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -11,7 +11,7 @@ diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) -diff(sin(x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index d80c0c70e..2a596f2cc 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -82,6 +82,21 @@ using add_mul_ret = double; #line 51 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; +using func_ret = double; + + +#line 55 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; +using func_call_ret = double; + + +#line 59 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; +using sin_call_ret = double; + + +#line 63 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -131,17 +146,29 @@ struct add_mul_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret; +struct func_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret; + +struct func_call_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret; + +struct sin_call_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 54 "pure2-autodiff-higher-order.cpp2" +#line 66 "pure2-autodiff-higher-order.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 65 "pure2-autodiff-higher-order.cpp2" +#line 77 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -232,6 +259,27 @@ auto main() -> int; r.construct(x + x * y); return std::move(r.value()); } +#line 55 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ + cpp2::impl::deferred_init r; +#line 56 "pure2-autodiff-higher-order.cpp2" + r.construct(x + y); + return std::move(r.value()); } + +#line 59 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ + cpp2::impl::deferred_init r; +#line 60 "pure2-autodiff-higher-order.cpp2" + r.construct(x * func(x, y)); + return std::move(r.value()); } + +#line 63 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ + cpp2::impl::deferred_init r; +#line 64 "pure2-autodiff-higher-order.cpp2" + r.construct(sin(x - y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0};r_d = x_d + y_d; @@ -330,25 +378,56 @@ auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; return { std::move(r), std::move(r_d) }; } -#line 56 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_2 {func_d(x, x_d, y, y_d)}; + + auto temp_1 {temp_2.r}; + + auto temp_1_d {cpp2::move(temp_2).r_d}; + r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); + r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {x_d - y_d}; + + auto temp_1 {x - y}; + r_d = CPP2_UFCS(sin)(cpp2::move(temp_1_d), temp_1); + r = sin(cpp2::move(temp_1)); + return { std::move(r), std::move(r_d) }; + } + +#line 68 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 60 "pure2-autodiff-higher-order.cpp2" +#line 72 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 63 "pure2-autodiff-higher-order.cpp2" +#line 75 "pure2-autodiff-higher-order.cpp2" } -#line 65 "pure2-autodiff-higher-order.cpp2" +#line 77 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 68 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; @@ -365,9 +444,9 @@ auto main() -> int{ write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); -// write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); -// write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); // write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); // write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); // write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index df1d345da..31cfcb1ec 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -110,6 +110,33 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + func:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y; + return; + } + + func_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func(x, y); + return; + } + + sin_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = sin(x - y); + return; + } + add_1_d:( in x: double, in x_d: cpp2::taylor, @@ -299,6 +326,56 @@ ad_test:/* @autodiff<"order=6"> @print */ type = r = x + temp_1; return; } + + func_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } + + func_call_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_2: _ = func_d(x, x_d, y, y_d); + temp_1: _ = temp_2.r; + temp_1_d: _ = temp_2.r_d; + r_d = x_d.mul(temp_1_d, x, temp_1); + r = x * temp_1; + return; + } + + sin_call_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: _ = x_d - y_d; + temp_1: _ = x - y; + r_d = temp_1_d.sin(temp_1); + r = sin(temp_1); + return; + } } ok (all Cpp2, passes safety checks) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 0ae197411..9721a0584 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -878,7 +878,7 @@ auto main() -> int{ write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x + y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); diff --git a/source/reflect.h b/source/reflect.h index e503cc72f..16d19f2d0 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -111,92 +111,92 @@ class simple_traverser; #line 3954 "reflect.h2" class autodiff_special_func; -#line 3977 "reflect.h2" +#line 3983 "reflect.h2" class autodiff_context; -#line 4063 "reflect.h2" +#line 4082 "reflect.h2" class autodiff_handler_base; -#line 4077 "reflect.h2" +#line 4096 "reflect.h2" class autodiff_expression_handler; -#line 4485 "reflect.h2" +#line 4504 "reflect.h2" class autodiff_stmt_handler; -#line 4868 "reflect.h2" +#line 4887 "reflect.h2" class expression_flags; -#line 4884 "reflect.h2" +#line 4903 "reflect.h2" class regex_token; -#line 4911 "reflect.h2" +#line 4930 "reflect.h2" class regex_token_check; -#line 4932 "reflect.h2" +#line 4951 "reflect.h2" class regex_token_code; -#line 4953 "reflect.h2" +#line 4972 "reflect.h2" class regex_token_empty; -#line 4971 "reflect.h2" +#line 4990 "reflect.h2" class regex_token_list; -#line 5023 "reflect.h2" +#line 5042 "reflect.h2" class parse_context_group_state; -#line 5084 "reflect.h2" +#line 5103 "reflect.h2" class parse_context_branch_reset_state; -#line 5127 "reflect.h2" +#line 5146 "reflect.h2" class parse_context; -#line 5528 "reflect.h2" +#line 5547 "reflect.h2" class generation_function_context; -#line 5546 "reflect.h2" +#line 5565 "reflect.h2" class generation_context; -#line 5745 "reflect.h2" +#line 5764 "reflect.h2" class alternative_token; -#line 5760 "reflect.h2" +#line 5779 "reflect.h2" class alternative_token_gen; -#line 5825 "reflect.h2" +#line 5844 "reflect.h2" class any_token; -#line 5842 "reflect.h2" +#line 5861 "reflect.h2" class atomic_group_token; -#line 5872 "reflect.h2" +#line 5891 "reflect.h2" class char_token; -#line 5987 "reflect.h2" +#line 6006 "reflect.h2" class class_token; -#line 6211 "reflect.h2" +#line 6230 "reflect.h2" class group_ref_token; -#line 6348 "reflect.h2" +#line 6367 "reflect.h2" class group_token; -#line 6695 "reflect.h2" +#line 6714 "reflect.h2" class lookahead_lookbehind_token; -#line 6790 "reflect.h2" +#line 6809 "reflect.h2" class range_token; -#line 6947 "reflect.h2" +#line 6966 "reflect.h2" class special_range_token; -#line 7033 "reflect.h2" +#line 7052 "reflect.h2" template class regex_generator; -#line 7290 "reflect.h2" +#line 7309 "reflect.h2" } } @@ -1645,79 +1645,88 @@ class autodiff_special_func { public: bool has_return; public: bool is_member; - public: std::string code; + public: std::string code; + public: std::string code_higher_order; - public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = ""); + public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = "", cpp2::impl::in code_higher_order_ = ""); -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" public: autodiff_special_func(autodiff_special_func const& that); -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" public: autodiff_special_func(autodiff_special_func&& that) noexcept; -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; -#line 3975 "reflect.h2" +#line 3981 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 3989 "reflect.h2" +#line 3995 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, true, false, "_rd_ = cos(_a1_) * _ad1_;\n" + "_r_ = sin(_a1_);\n", + "_rd_ = _ad1_.sin(_a1_);\n" "_r_ = sin(_a1_);\n" + ), autodiff_special_func("cos", 1, true, false, "_rd_ = -sin(_a1_) * _ad1_;\n" + "_r_ = cos(_a1_);\n", + "_rd_ = _ad1_.cos(_a1_);\n" "_r_ = cos(_a1_);\n" + ), autodiff_special_func("exp", 1, true, false, "_rd_ = exp(_a1_) * _ad1_;\n" + "_r_ = exp(_a1_);\n", + "_rd_ = _ad1_.exp(_a1_);\n" "_r_ = exp(_a1_);\n" ), autodiff_special_func("push_back", 1, false, true, "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n")}; -#line 4007 "reflect.h2" +#line 4021 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4011 "reflect.h2" +#line 4025 "reflect.h2" public: std::string ad_type {"double"}; public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4024 "reflect.h2" +#line 4038 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4032 "reflect.h2" +#line 4046 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4041 "reflect.h2" +#line 4055 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4055 "reflect.h2" +#line 4074 "reflect.h2" public: auto enter_function() & -> void; -#line 4059 "reflect.h2" +#line 4078 "reflect.h2" public: auto leave_function() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4061 "reflect.h2" +#line 4080 "reflect.h2" }; class autodiff_handler_base { @@ -1726,21 +1735,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4068 "reflect.h2" +#line 4087 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4072 "reflect.h2" +#line 4091 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4075 "reflect.h2" +#line 4094 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4081 "reflect.h2" +#line 4100 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1749,180 +1758,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4098 "reflect.h2" +#line 4117 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4117 "reflect.h2" +#line 4136 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4126 "reflect.h2" +#line 4145 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4164 "reflect.h2" +#line 4183 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4261 "reflect.h2" +#line 4280 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4294 "reflect.h2" +#line 4313 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4298 "reflect.h2" +#line 4317 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4302 "reflect.h2" +#line 4321 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4306 "reflect.h2" +#line 4325 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4310 "reflect.h2" +#line 4329 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4314 "reflect.h2" +#line 4333 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4318 "reflect.h2" +#line 4337 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4322 "reflect.h2" +#line 4341 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4326 "reflect.h2" +#line 4345 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4330 "reflect.h2" +#line 4349 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4334 "reflect.h2" +#line 4353 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4338 "reflect.h2" +#line 4357 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4362 "reflect.h2" +#line 4381 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4419 "reflect.h2" +#line 4438 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4423 "reflect.h2" +#line 4442 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4428 "reflect.h2" +#line 4447 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4455 "reflect.h2" +#line 4474 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4483 "reflect.h2" +#line 4502 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4489 "reflect.h2" +#line 4508 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4498 "reflect.h2" +#line 4517 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4503 "reflect.h2" +#line 4522 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4508 "reflect.h2" +#line 4527 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4526 "reflect.h2" +#line 4545 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4531 "reflect.h2" +#line 4550 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4536 "reflect.h2" +#line 4555 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4541 "reflect.h2" +#line 4560 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4549 "reflect.h2" +#line 4568 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4565 "reflect.h2" +#line 4584 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4612 "reflect.h2" +#line 4631 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4623 "reflect.h2" +#line 4642 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4651 "reflect.h2" +#line 4670 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4656 "reflect.h2" +#line 4675 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4660 "reflect.h2" +#line 4679 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4664 "reflect.h2" +#line 4683 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4668 "reflect.h2" +#line 4687 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4672 "reflect.h2" +#line 4691 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4676 "reflect.h2" +#line 4695 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4680 "reflect.h2" +#line 4699 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4684 "reflect.h2" +#line 4703 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4688 "reflect.h2" +#line 4707 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4692 "reflect.h2" +#line 4711 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4696 "reflect.h2" +#line 4715 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4700 "reflect.h2" +#line 4719 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4704 "reflect.h2" +#line 4723 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4709 "reflect.h2" +#line 4728 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4738 "reflect.h2" +#line 4757 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4742 "reflect.h2" +#line 4761 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4864 "reflect.h2" +#line 4883 "reflect.h2" using error_func = std::function x)>; -#line 4868 "reflect.h2" +#line 4887 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1957,20 +1966,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4876 "reflect.h2" +#line 4895 "reflect.h2" }; -#line 4884 "reflect.h2" +#line 4903 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4892 "reflect.h2" +#line 4911 "reflect.h2" public: explicit regex_token(); -#line 4897 "reflect.h2" +#line 4916 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1982,103 +1991,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4903 "reflect.h2" +#line 4922 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4909 "reflect.h2" +#line 4928 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4915 "reflect.h2" +#line 4934 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4922 "reflect.h2" +#line 4941 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4926 "reflect.h2" +#line 4945 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4927 "reflect.h2" +#line 4946 "reflect.h2" }; -#line 4930 "reflect.h2" +#line 4949 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4936 "reflect.h2" +#line 4955 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4943 "reflect.h2" +#line 4962 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4947 "reflect.h2" +#line 4966 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4948 "reflect.h2" +#line 4967 "reflect.h2" }; -#line 4951 "reflect.h2" +#line 4970 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4957 "reflect.h2" +#line 4976 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4961 "reflect.h2" +#line 4980 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4965 "reflect.h2" +#line 4984 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4966 "reflect.h2" +#line 4985 "reflect.h2" }; -#line 4969 "reflect.h2" +#line 4988 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4975 "reflect.h2" +#line 4994 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 4982 "reflect.h2" +#line 5001 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4988 "reflect.h2" +#line 5007 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 4994 "reflect.h2" +#line 5013 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5002 "reflect.h2" +#line 5021 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2086,10 +2095,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5014 "reflect.h2" +#line 5033 "reflect.h2" }; -#line 5017 "reflect.h2" +#line 5036 "reflect.h2" // // Parse and generation context. // @@ -2105,33 +2114,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5037 "reflect.h2" +#line 5056 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5044 "reflect.h2" +#line 5063 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5056 "reflect.h2" +#line 5075 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5061 "reflect.h2" +#line 5080 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5065 "reflect.h2" +#line 5084 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5079 "reflect.h2" +#line 5098 "reflect.h2" }; -#line 5082 "reflect.h2" +#line 5101 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2144,25 +2153,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5100 "reflect.h2" +#line 5119 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5106 "reflect.h2" +#line 5125 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5113 "reflect.h2" +#line 5132 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5120 "reflect.h2" +#line 5139 "reflect.h2" }; -#line 5123 "reflect.h2" +#line 5142 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2178,7 +2187,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5139 "reflect.h2" +#line 5158 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2186,64 +2195,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5150 "reflect.h2" +#line 5169 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5163 "reflect.h2" +#line 5182 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5171 "reflect.h2" +#line 5190 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5175 "reflect.h2" +#line 5194 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5179 "reflect.h2" +#line 5198 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5191 "reflect.h2" +#line 5210 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5198 "reflect.h2" +#line 5217 "reflect.h2" public: auto next_alternative() & -> void; -#line 5204 "reflect.h2" +#line 5223 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5210 "reflect.h2" +#line 5229 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5214 "reflect.h2" +#line 5233 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5225 "reflect.h2" +#line 5244 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5229 "reflect.h2" +#line 5248 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5235 "reflect.h2" +#line 5254 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5239 "reflect.h2" +#line 5258 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5246 "reflect.h2" +#line 5265 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5257 "reflect.h2" +#line 5276 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2251,51 +2260,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5301 "reflect.h2" +#line 5320 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5313 "reflect.h2" +#line 5332 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5326 "reflect.h2" +#line 5345 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5349 "reflect.h2" +#line 5368 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5366 "reflect.h2" +#line 5385 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5387 "reflect.h2" +#line 5406 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5397 "reflect.h2" +#line 5416 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5401 "reflect.h2" +#line 5420 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5457 "reflect.h2" +#line 5476 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5496 "reflect.h2" +#line 5515 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5511 "reflect.h2" +#line 5530 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2307,10 +2316,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5522 "reflect.h2" +#line 5541 "reflect.h2" }; -#line 5525 "reflect.h2" +#line 5544 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2320,16 +2329,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5539 "reflect.h2" +#line 5558 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5542 "reflect.h2" +#line 5561 "reflect.h2" }; -#line 5545 "reflect.h2" +#line 5564 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2349,68 +2358,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5567 "reflect.h2" +#line 5586 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5573 "reflect.h2" +#line 5592 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5582 "reflect.h2" +#line 5601 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5593 "reflect.h2" +#line 5612 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5600 "reflect.h2" +#line 5619 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5620 "reflect.h2" +#line 5639 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5630 "reflect.h2" +#line 5649 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5653 "reflect.h2" +#line 5672 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5661 "reflect.h2" +#line 5680 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5665 "reflect.h2" +#line 5684 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5671 "reflect.h2" +#line 5690 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5677 "reflect.h2" +#line 5696 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5687 "reflect.h2" +#line 5706 "reflect.h2" public: auto finish_context() & -> void; -#line 5695 "reflect.h2" +#line 5714 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5701 "reflect.h2" +#line 5720 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5705 "reflect.h2" +#line 5724 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5709 "reflect.h2" +#line 5728 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5733 "reflect.h2" +#line 5752 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2418,7 +2427,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5739 "reflect.h2" +#line 5758 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2438,27 +2447,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5758 "reflect.h2" +#line 5777 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5764 "reflect.h2" +#line 5783 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5771 "reflect.h2" +#line 5790 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5788 "reflect.h2" +#line 5807 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5795 "reflect.h2" +#line 5814 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5808 "reflect.h2" +#line 5827 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2466,19 +2475,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5820 "reflect.h2" +#line 5839 "reflect.h2" }; -#line 5823 "reflect.h2" +#line 5842 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5829 "reflect.h2" +#line 5848 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5833 "reflect.h2" +#line 5852 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2486,7 +2495,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5838 "reflect.h2" +#line 5857 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2494,17 +2503,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5846 "reflect.h2" +#line 5865 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5857 "reflect.h2" +#line 5876 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5865 "reflect.h2" +#line 5884 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2512,7 +2521,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5868 "reflect.h2" +#line 5887 "reflect.h2" }; // Regex syntax: a @@ -2520,34 +2529,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5876 "reflect.h2" +#line 5895 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5885 "reflect.h2" +#line 5904 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5891 "reflect.h2" +#line 5910 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5895 "reflect.h2" +#line 5914 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5918 "reflect.h2" +#line 5937 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5939 "reflect.h2" +#line 5958 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5957 "reflect.h2" +#line 5976 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5972 "reflect.h2" +#line 5991 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5978 "reflect.h2" +#line 5997 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2555,33 +2564,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 5982 "reflect.h2" +#line 6001 "reflect.h2" }; -#line 5985 "reflect.h2" +#line 6004 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 5991 "reflect.h2" +#line 6010 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6003 "reflect.h2" +#line 6022 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6129 "reflect.h2" +#line 6148 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6138 "reflect.h2" +#line 6157 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6143 "reflect.h2" +#line 6162 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2589,20 +2598,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6150 "reflect.h2" +#line 6169 "reflect.h2" }; -#line 6153 "reflect.h2" +#line 6172 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6194 "reflect.h2" +#line 6213 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6205 "reflect.h2" +#line 6224 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2612,20 +2621,20 @@ class class_token class group_ref_token : public regex_token { -#line 6215 "reflect.h2" +#line 6234 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6227 "reflect.h2" +#line 6246 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6328 "reflect.h2" +#line 6347 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6332 "reflect.h2" +#line 6351 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2633,10 +2642,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6335 "reflect.h2" +#line 6354 "reflect.h2" }; -#line 6338 "reflect.h2" +#line 6357 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2650,29 +2659,29 @@ class group_ref_token class group_token : public regex_token { -#line 6352 "reflect.h2" +#line 6371 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6374 "reflect.h2" +#line 6393 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6388 "reflect.h2" +#line 6407 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6547 "reflect.h2" +#line 6566 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6555 "reflect.h2" +#line 6574 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6573 "reflect.h2" +#line 6592 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6604 "reflect.h2" +#line 6623 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2681,25 +2690,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6611 "reflect.h2" +#line 6630 "reflect.h2" }; -#line 6614 "reflect.h2" +#line 6633 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6655 "reflect.h2" +#line 6674 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6675 "reflect.h2" +#line 6694 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6691 "reflect.h2" +#line 6710 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2707,20 +2716,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6699 "reflect.h2" +#line 6718 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6708 "reflect.h2" +#line 6727 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6719 "reflect.h2" +#line 6738 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6726 "reflect.h2" +#line 6745 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2728,26 +2737,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6729 "reflect.h2" +#line 6748 "reflect.h2" }; -#line 6732 "reflect.h2" +#line 6751 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6760 "reflect.h2" +#line 6779 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6788 "reflect.h2" +#line 6807 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6794 "reflect.h2" +#line 6813 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2757,22 +2766,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6874 "reflect.h2" +#line 6893 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6886 "reflect.h2" +#line 6905 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6899 "reflect.h2" +#line 6918 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6918 "reflect.h2" +#line 6937 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6928 "reflect.h2" +#line 6947 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6939 "reflect.h2" +#line 6958 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2780,16 +2789,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6942 "reflect.h2" +#line 6961 "reflect.h2" }; -#line 6945 "reflect.h2" +#line 6964 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6951 "reflect.h2" +#line 6970 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2798,7 +2807,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 6981 "reflect.h2" +#line 7000 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2807,14 +2816,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7003 "reflect.h2" +#line 7022 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7025 "reflect.h2" +#line 7044 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2835,24 +2844,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7048 "reflect.h2" +#line 7067 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7083 "reflect.h2" +#line 7102 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7097 "reflect.h2" +#line 7116 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7109 "reflect.h2" +#line 7128 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7164 "reflect.h2" +#line 7183 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2863,7 +2872,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7290 "reflect.h2" +#line 7309 "reflect.h2" } } @@ -7419,54 +7428,62 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // autodiff - stub // -#line 3962 "reflect.h2" - autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_) +#line 3963 "reflect.h2" + autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_, cpp2::impl::in code_higher_order_) : name{ name_ } , n_args{ n_args_ } , has_return{ has_return_ } , is_member{ is_member_ } - , code{ code_ }{ + , code{ code_ } + , code_higher_order{ code_higher_order_ }{ -#line 3968 "reflect.h2" +#line 3971 "reflect.h2" + if (CPP2_UFCS(empty)(code_higher_order)) { + code_higher_order = code; + } } -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) : name{ that.name } , n_args{ that.n_args } , has_return{ that.has_return } , is_member{ that.is_member } - , code{ that.code }{} -#line 3970 "reflect.h2" + , code{ that.code } + , code_higher_order{ that.code_higher_order }{} +#line 3976 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { name = that.name; n_args = that.n_args; has_return = that.has_return; is_member = that.is_member; code = that.code; + code_higher_order = that.code_higher_order; return *this; } -#line 3970 "reflect.h2" +#line 3976 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept : name{ std::move(that).name } , n_args{ std::move(that).n_args } , has_return{ std::move(that).has_return } , is_member{ std::move(that).is_member } - , code{ std::move(that).code }{} -#line 3970 "reflect.h2" + , code{ std::move(that).code } + , code_higher_order{ std::move(that).code_higher_order }{} +#line 3976 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { name = std::move(that).name; n_args = std::move(that).n_args; has_return = std::move(that).has_return; is_member = std::move(that).is_member; code = std::move(that).code; + code_higher_order = std::move(that).code_higher_order; return *this; }// Default copy. -#line 3972 "reflect.h2" +#line 3978 "reflect.h2" [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; } -#line 3980 "reflect.h2" +#line 3986 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7479,19 +7496,19 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in /* has_return = */ /* is_member = */ -#line 3994 "reflect.h2" +#line 4003 "reflect.h2" /* has_return = */ /* is_member = */ -#line 3998 "reflect.h2" +#line 4010 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4002 "reflect.h2" +#line 4016 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4010 "reflect.h2" +#line 4024 "reflect.h2" // Members depending on order -#line 4013 "reflect.h2" +#line 4027 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7503,17 +7520,17 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4024 "reflect.h2" +#line 4038 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4026 "reflect.h2" +#line 4040 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4032 "reflect.h2" +#line 4046 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ if (order == 1) { @@ -7523,11 +7540,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return string_util::replace_all(type, "double", ad_type); } -#line 4041 "reflect.h2" +#line 4055 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4042 "reflect.h2" +#line 4056 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7535,42 +7552,47 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in for ( auto const& func : special_funcs ) { if (CPP2_UFCS(is_match)(func, lookup)) { m.value() = true; - code.value() = func.code; + if (is_taylor()) { + code.value() = func.code_higher_order; + } + else { + code.value() = func.code; + } return { std::move(m.value()), std::move(code.value()) }; } }return { std::move(m.value()), std::move(code.value()) }; } -#line 4055 "reflect.h2" +#line 4074 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4059 "reflect.h2" +#line 4078 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4068 "reflect.h2" +#line 4087 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4070 "reflect.h2" +#line 4089 "reflect.h2" } -#line 4068 "reflect.h2" +#line 4087 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4070 "reflect.h2" +#line 4089 "reflect.h2" } -#line 4072 "reflect.h2" +#line 4091 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4087 "reflect.h2" +#line 4106 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7578,13 +7600,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4093 "reflect.h2" +#line 4112 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4098 "reflect.h2" +#line 4117 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7604,7 +7626,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4117 "reflect.h2" +#line 4136 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7614,7 +7636,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4126 "reflect.h2" +#line 4145 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7653,7 +7675,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4164 "reflect.h2" +#line 4183 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7661,7 +7683,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4170 "reflect.h2" +#line 4189 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7675,7 +7697,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4182 "reflect.h2" +#line 4201 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7698,7 +7720,7 @@ auto i{0}; { auto i{0}; -#line 4203 "reflect.h2" +#line 4222 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7723,7 +7745,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4226 "reflect.h2" +#line 4245 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7759,7 +7781,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation. } -#line 4261 "reflect.h2" +#line 4280 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7784,75 +7806,75 @@ auto i{0}; { auto i{1}; -#line 4284 "reflect.h2" +#line 4303 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4289 "reflect.h2" +#line 4308 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4294 "reflect.h2" +#line 4313 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4298 "reflect.h2" +#line 4317 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4302 "reflect.h2" +#line 4321 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4306 "reflect.h2" +#line 4325 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4310 "reflect.h2" +#line 4329 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4314 "reflect.h2" +#line 4333 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4318 "reflect.h2" +#line 4337 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4322 "reflect.h2" +#line 4341 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4326 "reflect.h2" +#line 4345 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4330 "reflect.h2" +#line 4349 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4334 "reflect.h2" +#line 4353 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4338 "reflect.h2" +#line 4357 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7877,7 +7899,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4362 "reflect.h2" +#line 4381 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7916,7 +7938,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4401 "reflect.h2" +#line 4420 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7935,18 +7957,18 @@ auto i{1}; } } -#line 4419 "reflect.h2" +#line 4438 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4423 "reflect.h2" +#line 4442 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4428 "reflect.h2" +#line 4447 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7955,7 +7977,7 @@ auto i{1}; { auto i{0}; -#line 4435 "reflect.h2" +#line 4454 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7969,7 +7991,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4447 "reflect.h2" +#line 4466 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7978,7 +8000,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4455 "reflect.h2" +#line 4474 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8008,26 +8030,26 @@ auto i{0}; }}}} } -#line 4493 "reflect.h2" +#line 4512 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4496 "reflect.h2" +#line 4515 "reflect.h2" } -#line 4498 "reflect.h2" +#line 4517 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4503 "reflect.h2" +#line 4522 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4508 "reflect.h2" +#line 4527 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8045,22 +8067,22 @@ auto i{0}; } } -#line 4526 "reflect.h2" +#line 4545 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4531 "reflect.h2" +#line 4550 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4536 "reflect.h2" +#line 4555 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4541 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8068,7 +8090,7 @@ auto i{0}; diff += "}\n"; } -#line 4549 "reflect.h2" +#line 4568 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8084,7 +8106,7 @@ auto i{0}; } } -#line 4565 "reflect.h2" +#line 4584 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8131,7 +8153,7 @@ auto i{0}; }} } -#line 4612 "reflect.h2" +#line 4631 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8143,7 +8165,7 @@ auto i{0}; } } -#line 4623 "reflect.h2" +#line 4642 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8172,79 +8194,79 @@ auto i{0}; } } -#line 4651 "reflect.h2" +#line 4670 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4656 "reflect.h2" +#line 4675 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4660 "reflect.h2" +#line 4679 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4664 "reflect.h2" +#line 4683 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4668 "reflect.h2" +#line 4687 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4672 "reflect.h2" +#line 4691 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4676 "reflect.h2" +#line 4695 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4680 "reflect.h2" +#line 4699 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4684 "reflect.h2" +#line 4703 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4688 "reflect.h2" +#line 4707 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4692 "reflect.h2" +#line 4711 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4696 "reflect.h2" +#line 4715 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4700 "reflect.h2" +#line 4719 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4704 "reflect.h2" +#line 4723 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4709 "reflect.h2" +#line 4728 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8253,7 +8275,7 @@ auto i{0}; { auto i{0}; -#line 4716 "reflect.h2" +#line 4735 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8267,7 +8289,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4728 "reflect.h2" +#line 4747 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8278,13 +8300,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4738 "reflect.h2" +#line 4757 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4744 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8368,10 +8390,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } -#line 4828 "reflect.h2" +#line 4847 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4831 "reflect.h2" +#line 4850 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8481,7 +8503,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4850 "reflect.h2" +#line 4869 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8497,11 +8519,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4866 "reflect.h2" +#line 4885 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4870 "reflect.h2" +#line 4889 "reflect.h2" // mod: i // mod: m // mod: s @@ -8509,116 +8531,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4879 "reflect.h2" +#line 4898 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4888 "reflect.h2" +#line 4907 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4890 "reflect.h2" +#line 4909 "reflect.h2" } -#line 4892 "reflect.h2" +#line 4911 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4894 "reflect.h2" +#line 4913 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4900 "reflect.h2" +#line 4919 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4901 "reflect.h2" +#line 4920 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4902 "reflect.h2" +#line 4921 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4917 "reflect.h2" +#line 4936 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4920 "reflect.h2" +#line 4939 "reflect.h2" } -#line 4922 "reflect.h2" +#line 4941 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4926 "reflect.h2" +#line 4945 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4938 "reflect.h2" +#line 4957 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4941 "reflect.h2" +#line 4960 "reflect.h2" } -#line 4943 "reflect.h2" +#line 4962 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4947 "reflect.h2" +#line 4966 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4957 "reflect.h2" +#line 4976 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4959 "reflect.h2" +#line 4978 "reflect.h2" } -#line 4961 "reflect.h2" +#line 4980 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4965 "reflect.h2" +#line 4984 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4977 "reflect.h2" +#line 4996 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4980 "reflect.h2" +#line 4999 "reflect.h2" } -#line 4982 "reflect.h2" +#line 5001 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 4988 "reflect.h2" +#line 5007 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 4994 "reflect.h2" +#line 5013 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8627,7 +8649,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5002 "reflect.h2" +#line 5021 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8643,7 +8665,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5030 "reflect.h2" +#line 5049 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8651,14 +8673,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5038 "reflect.h2" +#line 5057 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5045 "reflect.h2" +#line 5064 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8670,15 +8692,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5057 "reflect.h2" +#line 5076 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5062 "reflect.h2" +#line 5081 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5066 "reflect.h2" +#line 5085 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8699,7 +8721,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5092 "reflect.h2" +#line 5111 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8708,20 +8730,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5101 "reflect.h2" +#line 5120 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5107 "reflect.h2" +#line 5126 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5114 "reflect.h2" +#line 5133 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8736,16 +8758,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5144 "reflect.h2" +#line 5163 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5148 "reflect.h2" +#line 5167 "reflect.h2" } -#line 5154 "reflect.h2" +#line 5173 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8755,7 +8777,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5164 "reflect.h2" +#line 5183 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8763,17 +8785,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5171 "reflect.h2" +#line 5190 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5175 "reflect.h2" +#line 5194 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5182 "reflect.h2" +#line 5201 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8783,7 +8805,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5191 "reflect.h2" +#line 5210 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8791,24 +8813,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5198 "reflect.h2" +#line 5217 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5206 "reflect.h2" +#line 5225 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5210 "reflect.h2" +#line 5229 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5214 "reflect.h2" +#line 5233 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8820,22 +8842,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5225 "reflect.h2" +#line 5244 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5231 "reflect.h2" +#line 5250 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5235 "reflect.h2" +#line 5254 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5239 "reflect.h2" +#line 5258 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8843,7 +8865,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5246 "reflect.h2" +#line 5265 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8855,10 +8877,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5259 "reflect.h2" +#line 5278 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5262 "reflect.h2" +#line 5281 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8898,7 +8920,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5302 "reflect.h2" +#line 5321 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8910,14 +8932,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5313 "reflect.h2" +#line 5332 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5314 "reflect.h2" +#line 5333 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5315 "reflect.h2" +#line 5334 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5317 "reflect.h2" +#line 5336 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8927,10 +8949,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5326 "reflect.h2" +#line 5345 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5328 "reflect.h2" +#line 5347 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8952,14 +8974,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5349 "reflect.h2" +#line 5368 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5350 "reflect.h2" +#line 5369 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5351 "reflect.h2" +#line 5370 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5353 "reflect.h2" +#line 5372 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8973,7 +8995,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5366 "reflect.h2" +#line 5385 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -8995,7 +9017,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5387 "reflect.h2" +#line 5406 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9006,12 +9028,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5397 "reflect.h2" +#line 5416 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5398 "reflect.h2" +#line 5417 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5403 "reflect.h2" +#line 5422 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9066,7 +9088,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5457 "reflect.h2" +#line 5476 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9106,7 +9128,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5496 "reflect.h2" +#line 5515 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9122,21 +9144,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5513 "reflect.h2" +#line 5532 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5514 "reflect.h2" +#line 5533 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5515 "reflect.h2" +#line 5534 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5517 "reflect.h2" +#line 5536 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5532 "reflect.h2" +#line 5551 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9144,7 +9166,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5539 "reflect.h2" +#line 5558 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9154,22 +9176,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5557 "reflect.h2" +#line 5576 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5562 "reflect.h2" +#line 5581 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5568 "reflect.h2" +#line 5587 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5574 "reflect.h2" +#line 5593 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9178,7 +9200,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5582 "reflect.h2" +#line 5601 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9190,7 +9212,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5593 "reflect.h2" +#line 5612 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9198,7 +9220,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5600 "reflect.h2" +#line 5619 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9219,7 +9241,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5621 "reflect.h2" +#line 5640 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9229,7 +9251,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5631 "reflect.h2" +#line 5650 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9252,33 +9274,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5655 "reflect.h2" +#line 5674 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5661 "reflect.h2" +#line 5680 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5665 "reflect.h2" +#line 5684 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5671 "reflect.h2" +#line 5690 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5679 "reflect.h2" +#line 5698 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9287,7 +9309,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5687 "reflect.h2" +#line 5706 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9296,22 +9318,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5697 "reflect.h2" +#line 5716 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5701 "reflect.h2" +#line 5720 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5705 "reflect.h2" +#line 5724 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5709 "reflect.h2" +#line 5728 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9335,18 +9357,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5734 "reflect.h2" +#line 5753 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5749 "reflect.h2" +#line 5768 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5751 "reflect.h2" +#line 5770 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9357,15 +9379,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5766 "reflect.h2" +#line 5785 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5769 "reflect.h2" +#line 5788 "reflect.h2" } -#line 5771 "reflect.h2" +#line 5790 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9383,7 +9405,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5788 "reflect.h2" +#line 5807 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9391,7 +9413,7 @@ generation_function_context::generation_function_context(){} } } -#line 5795 "reflect.h2" +#line 5814 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9405,7 +9427,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5808 "reflect.h2" +#line 5827 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9421,14 +9443,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5829 "reflect.h2" +#line 5848 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5831 "reflect.h2" +#line 5850 "reflect.h2" } -#line 5833 "reflect.h2" +#line 5852 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9437,11 +9459,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5848 "reflect.h2" +#line 5867 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5850 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9449,7 +9471,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5857 "reflect.h2" +#line 5876 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9458,37 +9480,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5865 "reflect.h2" +#line 5884 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5879 "reflect.h2" +#line 5898 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5883 "reflect.h2" +#line 5902 "reflect.h2" } -#line 5885 "reflect.h2" +#line 5904 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5889 "reflect.h2" +#line 5908 "reflect.h2" } -#line 5891 "reflect.h2" +#line 5910 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5895 "reflect.h2" +#line 5914 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9497,14 +9519,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5901 "reflect.h2" +#line 5920 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5906 "reflect.h2" +#line 5925 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9517,7 +9539,7 @@ size_t i{0}; } } -#line 5918 "reflect.h2" +#line 5937 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9539,7 +9561,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5939 "reflect.h2" +#line 5958 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9558,7 +9580,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5957 "reflect.h2" +#line 5976 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9574,14 +9596,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5972 "reflect.h2" +#line 5991 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5978 "reflect.h2" +#line 5997 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9589,19 +9611,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 5995 "reflect.h2" +#line 6014 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 5996 "reflect.h2" +#line 6015 "reflect.h2" { -#line 6001 "reflect.h2" +#line 6020 "reflect.h2" } -#line 6004 "reflect.h2" +#line 6023 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9727,7 +9749,7 @@ size_t i{0}; ); } -#line 6129 "reflect.h2" +#line 6148 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9737,13 +9759,13 @@ size_t i{0}; ); } -#line 6138 "reflect.h2" +#line 6157 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6143 "reflect.h2" +#line 6162 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9754,12 +9776,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6155 "reflect.h2" +#line 6174 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6160 "reflect.h2" +#line 6179 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9793,7 +9815,7 @@ size_t i{0}; } -#line 6196 "reflect.h2" +#line 6215 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9802,19 +9824,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6219 "reflect.h2" +#line 6238 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6220 "reflect.h2" +#line 6239 "reflect.h2" { -#line 6225 "reflect.h2" +#line 6244 "reflect.h2" } -#line 6227 "reflect.h2" +#line 6246 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9916,19 +9938,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6328 "reflect.h2" +#line 6347 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6332 "reflect.h2" +#line 6351 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6356 "reflect.h2" +#line 6375 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9947,7 +9969,7 @@ size_t i{0}; return r; } -#line 6374 "reflect.h2" +#line 6393 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9962,7 +9984,7 @@ size_t i{0}; return r; } -#line 6388 "reflect.h2" +#line 6407 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10122,7 +10144,7 @@ size_t i{0}; } } -#line 6547 "reflect.h2" +#line 6566 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10131,7 +10153,7 @@ size_t i{0}; return r; } -#line 6555 "reflect.h2" +#line 6574 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10150,7 +10172,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6573 "reflect.h2" +#line 6592 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10182,7 +10204,7 @@ size_t i{0}; } } -#line 6604 "reflect.h2" +#line 6623 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10193,7 +10215,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6616 "reflect.h2" +#line 6635 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10232,7 +10254,7 @@ size_t i{0}; return r; } -#line 6657 "reflect.h2" +#line 6676 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10250,7 +10272,7 @@ size_t i{0}; }} } -#line 6677 "reflect.h2" +#line 6696 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10264,16 +10286,16 @@ size_t i{0}; } } -#line 6703 "reflect.h2" +#line 6722 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6706 "reflect.h2" +#line 6725 "reflect.h2" } -#line 6708 "reflect.h2" +#line 6727 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10285,7 +10307,7 @@ size_t i{0}; } } -#line 6719 "reflect.h2" +#line 6738 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10293,14 +10315,14 @@ size_t i{0}; return r; } -#line 6726 "reflect.h2" +#line 6745 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6734 "reflect.h2" +#line 6753 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10326,7 +10348,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6762 "reflect.h2" +#line 6781 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10352,11 +10374,11 @@ size_t i{0}; return r; } -#line 6799 "reflect.h2" +#line 6818 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6801 "reflect.h2" +#line 6820 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10430,7 +10452,7 @@ size_t i{0}; return nullptr; } -#line 6874 "reflect.h2" +#line 6893 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10443,7 +10465,7 @@ size_t i{0}; }} } -#line 6886 "reflect.h2" +#line 6905 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10457,7 +10479,7 @@ size_t i{0}; }} } -#line 6899 "reflect.h2" +#line 6918 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10477,7 +10499,7 @@ size_t i{0}; return r; } -#line 6918 "reflect.h2" +#line 6937 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10488,7 +10510,7 @@ size_t i{0}; return r; } -#line 6928 "reflect.h2" +#line 6947 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10500,14 +10522,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6939 "reflect.h2" +#line 6958 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6951 "reflect.h2" +#line 6970 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10531,7 +10553,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6975 "reflect.h2" +#line 6994 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10541,7 +10563,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 6987 "reflect.h2" +#line 7006 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10557,7 +10579,7 @@ size_t i{0}; } } -#line 7007 "reflect.h2" +#line 7026 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10575,15 +10597,15 @@ size_t i{0}; }} } -#line 7043 "reflect.h2" +#line 7062 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7046 "reflect.h2" +#line 7065 "reflect.h2" } -#line 7048 "reflect.h2" +#line 7067 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10619,7 +10641,7 @@ size_t i{0}; return source; } -#line 7083 "reflect.h2" +#line 7102 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10635,7 +10657,7 @@ size_t i{0}; } } -#line 7099 "reflect.h2" +#line 7118 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10644,7 +10666,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10699,7 +10721,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7168 "reflect.h2" +#line 7187 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10821,7 +10843,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7290 "reflect.h2" +#line 7309 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index fc953d5b8..e4cfc14f6 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3957,14 +3957,20 @@ autodiff_special_func: type = { public has_return: bool; public is_member : bool; - public code: std::string; + public code : std::string; + public code_higher_order: std::string; - operator=: (out this, name_: std::string, n_args_: int, has_return_: bool, is_member_: bool, code_: std::string = "") = { - name = name_; - n_args = n_args_; - has_return = has_return_; - is_member = is_member_; - code = code_; + operator=: (out this, name_: std::string, n_args_: int, has_return_: bool, is_member_: bool, code_: std::string = "", code_higher_order_: std::string = "") = { + name = name_; + n_args = n_args_; + has_return = has_return_; + is_member = is_member_; + code = code_; + code_higher_order = code_higher_order_; + + if code_higher_order.empty() { + code_higher_order = code; + } } operator=: (out this, that) = {} // Default copy. @@ -3989,15 +3995,23 @@ autodiff_context: type = { public special_funcs : std::vector = ( autodiff_special_func("sin", 1, /* has_return = */ true, /* is_member = */ false, "_rd_ = cos(_a1_) * _ad1_;\n" - "_r_ = sin(_a1_);\n" + "_r_ = sin(_a1_);\n", + "_rd_ = _ad1_.sin(_a1_);\n" + "_r_ = sin(_a1_);\n", + ), autodiff_special_func("cos", 1, /* has_return = */ true, /* is_member = */ false, "_rd_ = -sin(_a1_) * _ad1_;\n" - "_r_ = cos(_a1_);\n" + "_r_ = cos(_a1_);\n", + "_rd_ = _ad1_.cos(_a1_);\n" + "_r_ = cos(_a1_);\n", + ), autodiff_special_func("exp", 1, /* has_return = */ true, /* is_member = */ false, "_rd_ = exp(_a1_) * _ad1_;\n" - "_r_ = exp(_a1_);\n" + "_r_ = exp(_a1_);\n", + "_rd_ = _ad1_.exp(_a1_);\n" + "_r_ = exp(_a1_);\n", ), autodiff_special_func("push_back", 1, /* has_return = */ false, /* is_member = */ true, "_o_.push_back(_a1_);\n" @@ -4046,7 +4060,12 @@ autodiff_context: type = { for special_funcs do (func) { if func.is_match(lookup) { m = true; - code = func.code; + if is_taylor() { + code = func.code_higher_order; + } + else { + code = func.code; + } return; } } From b930fe7ec5b0a3abd74a35b19eecba31f231b751 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Wed, 13 Aug 2025 14:18:02 +0200 Subject: [PATCH 26/54] Remaining tests for higher order derivatives. --- include/cpp2taylor.h | 164 ++-- include/cpp2taylor.h2 | 7 + .../pure2-autodiff-higher-order.cpp2 | 112 ++- .../pure2-autodiff-higher-order.cpp.execution | 88 ++ .../pure2-autodiff-higher-order.cpp | 416 +++++++- .../pure2-autodiff-higher-order.cpp2.output | 375 ++++++++ .../test-results/pure2-autodiff.cpp | 2 +- .../test-results/pure2-autodiff.cpp2.output | 2 +- source/reflect.h | 901 +++++++++--------- source/reflect.h2 | 9 +- 10 files changed, 1526 insertions(+), 550 deletions(-) diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index 2fbdcc0ee..e07cb3171 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -16,7 +16,7 @@ namespace cpp2 { template class taylor; -#line 218 "cpp2taylor.h2" +#line 225 "cpp2taylor.h2" } @@ -46,62 +46,67 @@ template class taylor { #line 13 "cpp2taylor.h2" public: auto operator=(taylor&& that) noexcept -> taylor& ; + public: taylor(std::initializer_list const& l); +#line 15 "cpp2taylor.h2" + public: auto operator=(std::initializer_list const& l) -> taylor& ; + +#line 22 "cpp2taylor.h2" // C++ interface public: [[nodiscard]] auto operator[](cpp2::impl::in k) const& -> R; -#line 27 "cpp2taylor.h2" +#line 34 "cpp2taylor.h2" public: auto set(cpp2::impl::in k, cpp2::impl::in value) & -> void; -#line 37 "cpp2taylor.h2" +#line 44 "cpp2taylor.h2" // C++2 interface / AD interface public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; -#line 49 "cpp2taylor.h2" +#line 56 "cpp2taylor.h2" // Overload for simple handling of connected adds. public: [[nodiscard]] auto operator+(cpp2::impl::in o) const& -> taylor; -#line 54 "cpp2taylor.h2" +#line 61 "cpp2taylor.h2" // Overload for simple handling of connected minuses. public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; -#line 59 "cpp2taylor.h2" +#line 66 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 70 "cpp2taylor.h2" +#line 77 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 81 "cpp2taylor.h2" +#line 88 "cpp2taylor.h2" public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 94 "cpp2taylor.h2" +#line 101 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 112 "cpp2taylor.h2" +#line 119 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; -#line 131 "cpp2taylor.h2" +#line 138 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; -#line 150 "cpp2taylor.h2" +#line 157 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; -#line 169 "cpp2taylor.h2" +#line 176 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; -#line 186 "cpp2taylor.h2" +#line 193 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; -#line 196 "cpp2taylor.h2" +#line 203 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; -#line 205 "cpp2taylor.h2" +#line 212 "cpp2taylor.h2" }; template [[nodiscard]] auto to_string(taylor const& o) -> std::string; -#line 218 "cpp2taylor.h2" +#line 225 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H @@ -144,38 +149,65 @@ namespace cpp2 { v = std::move(that).v; return *this; } +#line 15 "cpp2taylor.h2" + template taylor::taylor(std::initializer_list const& l){ +{ +auto i{1}; + #line 17 "cpp2taylor.h2" + for ( auto const& cur : l ) { + set(i, cur); + } +} +#line 20 "cpp2taylor.h2" + } +#line 15 "cpp2taylor.h2" + template auto taylor::operator=(std::initializer_list const& l) -> taylor& { + v = {}; +{ +auto i{1}; + +#line 17 "cpp2taylor.h2" + for ( auto const& cur : l ) { + set(i, cur); + } +} + return *this; +#line 20 "cpp2taylor.h2" + } + +#line 24 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator[](cpp2::impl::in k) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } R r {CPP2_ASSERT_IN_BOUNDS(v, k - 1)}; { auto i{2}; -#line 21 "cpp2taylor.h2" +#line 28 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { r *= i; } } -#line 24 "cpp2taylor.h2" +#line 31 "cpp2taylor.h2" return r; } -#line 27 "cpp2taylor.h2" +#line 34 "cpp2taylor.h2" template auto taylor::set(cpp2::impl::in k, cpp2::impl::in value) & -> void{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } CPP2_ASSERT_IN_BOUNDS(v, k - 1) = value; { auto i{2}; -#line 32 "cpp2taylor.h2" +#line 39 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(v, k - 1)),i); } } -#line 35 "cpp2taylor.h2" +#line 42 "cpp2taylor.h2" } -#line 39 "cpp2taylor.h2" +#line 46 "cpp2taylor.h2" template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 0, _1 = i, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } @@ -186,72 +218,72 @@ auto i{2}; return CPP2_ASSERT_IN_BOUNDS(v, i - 1); } -#line 50 "cpp2taylor.h2" +#line 57 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+(cpp2::impl::in o) const& -> taylor{ return add(o, 0.0, 0.0); // Primal values are not required. } -#line 55 "cpp2taylor.h2" +#line 62 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-(cpp2::impl::in o) const& -> taylor{ return sub(o, 0.0, 0.0); // Primal values are not required. } -#line 59 "cpp2taylor.h2" +#line 66 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 63 "cpp2taylor.h2" +#line 70 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } -#line 67 "cpp2taylor.h2" +#line 74 "cpp2taylor.h2" return r; } -#line 70 "cpp2taylor.h2" +#line 77 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 74 "cpp2taylor.h2" +#line 81 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } -#line 78 "cpp2taylor.h2" +#line 85 "cpp2taylor.h2" return r; } -#line 81 "cpp2taylor.h2" +#line 88 "cpp2taylor.h2" template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 85 "cpp2taylor.h2" +#line 92 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{0}; -#line 87 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } -#line 90 "cpp2taylor.h2" +#line 97 "cpp2taylor.h2" } } -#line 91 "cpp2taylor.h2" +#line 98 "cpp2taylor.h2" return r; } -#line 94 "cpp2taylor.h2" +#line 101 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; @@ -260,26 +292,26 @@ auto j{0}; { auto k{1}; -#line 101 "cpp2taylor.h2" +#line 108 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; -#line 104 "cpp2taylor.h2" +#line 111 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } -#line 107 "cpp2taylor.h2" +#line 114 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 109 "cpp2taylor.h2" +#line 116 "cpp2taylor.h2" return r; } -#line 112 "cpp2taylor.h2" +#line 119 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; @@ -288,27 +320,27 @@ auto j{0}; { auto k{1}; -#line 119 "cpp2taylor.h2" +#line 126 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; -#line 122 "cpp2taylor.h2" +#line 129 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } -#line 125 "cpp2taylor.h2" +#line 132 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 128 "cpp2taylor.h2" +#line 135 "cpp2taylor.h2" return r; } -#line 131 "cpp2taylor.h2" +#line 138 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; @@ -317,27 +349,27 @@ auto j{1}; { auto k{1}; -#line 138 "cpp2taylor.h2" +#line 145 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; -#line 141 "cpp2taylor.h2" +#line 148 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } -#line 144 "cpp2taylor.h2" +#line 151 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } -#line 147 "cpp2taylor.h2" +#line 154 "cpp2taylor.h2" return r; } -#line 150 "cpp2taylor.h2" +#line 157 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; @@ -346,52 +378,52 @@ auto j{1}; { auto k{1}; -#line 157 "cpp2taylor.h2" +#line 164 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 159 "cpp2taylor.h2" +#line 166 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } -#line 162 "cpp2taylor.h2" +#line 169 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } -#line 165 "cpp2taylor.h2" +#line 172 "cpp2taylor.h2" return r; } -#line 169 "cpp2taylor.h2" +#line 176 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; -#line 174 "cpp2taylor.h2" +#line 181 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 176 "cpp2taylor.h2" +#line 183 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); } } -#line 180 "cpp2taylor.h2" +#line 187 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } -#line 183 "cpp2taylor.h2" +#line 190 "cpp2taylor.h2" } -#line 186 "cpp2taylor.h2" +#line 193 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -402,7 +434,7 @@ auto j{1}; return r; } -#line 196 "cpp2taylor.h2" +#line 203 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -413,18 +445,18 @@ auto j{1}; return r; } -#line 207 "cpp2taylor.h2" +#line 214 "cpp2taylor.h2" template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ std::string r {"("}; { auto i{1}; -#line 210 "cpp2taylor.h2" +#line 217 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; } } -#line 213 "cpp2taylor.h2" +#line 220 "cpp2taylor.h2" r += " )"; return r; diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index cf122bd87..fc6432459 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -12,6 +12,13 @@ taylor: type = { } operator=:(out this, that) = {} + operator=:(out this, l: std::initializer_list) = { + (copy i := 1) + for l do (cur) { + set(i, cur); + } + } + // C++ interface operator[]: (this, k: int) -> R = { diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index 1d700a1f1..bdfec488f 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -63,6 +63,96 @@ ad_test: @autodiff<"order=6"> @print type = { sin_call: (x: double, y: double) -> (r: double) = { r = sin(x - y); } + + if_branch: (x: double, y: double) -> (r: double) = { + r = x; + + if x < 0.0 { + r = y; + } + } + + if_else_branch: (x: double, y: double) -> (r: double) = { + if x < 0.0 { + r = y; + } + else { + r = x; + } + } + + direct_return: (x: double, y: double) -> double = { + return x + y; + } + + intermediate_var: (x: double, y: double) -> (r: double) = { + t: double = x + y; + + r = t; + } + + intermediate_passive_var: (x: double, y: double) -> (r: double) = { + i: int = (); // TODO: Handle as passive when type information on call side is available. + r = x + y; + i = 2; + + _ = i; + } + + intermediate_untyped: (x: double, y: double) -> (r: double) = { + t := 0.0; + t = x + y; + + r = t; + } + + intermediate_default_init: (x: double, y: double) -> (r: double) = { + t: double = (); + t = x + y; + + r = t; + } + + intermediate_no_init: (x: double, y: double) -> (r: double) = { + t: double; + t = x + y; + + r = t; + } + + while_loop: (x: double, y: double) -> (r: double) = { + i: int = 0; + + r = x; + while i < 2 next (i += 1) { + r = r + y ; + } + } + + do_while_loop: (x: double, y: double) -> (r: double) = { + i: int = 0; + + r = x; + do { + r = r + y ; + } + next (i += 1) + while i < 2; + } + + for_loop: (x: double, y: double) -> (r: double) = { + v: std::vector = (); + + v.push_back(x); + v.push_back(y); + + r = 0.0; + for v + do (t) + { + r = r + t; + } + } } write_output: (func: std::string, x: double, x_d: ad_type, y: double, y_d: ad_type, ret) = { @@ -96,15 +186,15 @@ main: () = { write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); -// write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); -// write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); -// write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); -// write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); -// write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); -// write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); -// write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); -// write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); -// write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); -// write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); -// write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index 4b430cd55..f5a4a8c98 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -110,3 +110,91 @@ diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0 d4 = -0.841471 d5 = -0.540302 d6 = 0.841471 +diff(if branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(if else branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(direct return) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate passive var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate untyped) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate default init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate no init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(do while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(for loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 2a596f2cc..c1e64eb9e 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -97,6 +97,59 @@ using sin_call_ret = double; #line 63 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; +using if_branch_ret = double; + + +#line 67 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; +using if_else_branch_ret = double; + + +#line 75 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; + +#line 84 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; +using intermediate_var_ret = double; + + +#line 88 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; +using intermediate_passive_var_ret = double; + + +#line 94 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; +using intermediate_untyped_ret = double; + + +#line 102 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; +using intermediate_default_init_ret = double; + + +#line 109 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; +using intermediate_no_init_ret = double; + + +#line 116 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; +using while_loop_ret = double; + + +#line 123 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; +using do_while_loop_ret = double; + + +#line 132 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; +using for_loop_ret = double; + + +#line 143 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -158,17 +211,61 @@ struct sin_call_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret; +struct if_branch_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto if_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_branch_d_ret; + +struct if_else_branch_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto if_else_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_else_branch_d_ret; + +struct direct_return_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto direct_return_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> direct_return_d_ret; + +struct intermediate_var_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto intermediate_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_var_d_ret; + +struct intermediate_passive_var_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_passive_var_d_ret; + +struct intermediate_untyped_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_untyped_d_ret; + +struct intermediate_default_init_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_default_init_d_ret; + +struct intermediate_no_init_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_no_init_d_ret; + +struct while_loop_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> while_loop_d_ret; + +struct do_while_loop_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto do_while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> do_while_loop_d_ret; + +struct for_loop_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> for_loop_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 66 "pure2-autodiff-higher-order.cpp2" +#line 156 "pure2-autodiff-higher-order.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 77 "pure2-autodiff-higher-order.cpp2" +#line 167 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -280,6 +377,127 @@ auto main() -> int; r.construct(sin(x - y)); return std::move(r.value()); } +#line 67 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ + cpp2::impl::deferred_init r; +#line 68 "pure2-autodiff-higher-order.cpp2" + r.construct(x); + + if (cpp2::impl::cmp_less(x,0.0)) { + r.value() = y; + }return std::move(r.value()); + } + +#line 75 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ + cpp2::impl::deferred_init r; +#line 76 "pure2-autodiff-higher-order.cpp2" + if (cpp2::impl::cmp_less(x,0.0)) { + r.construct(y); + } + else { + r.construct(x); + }return std::move(r.value()); + } + +#line 84 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ + return x + y; + } + +#line 88 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ + cpp2::impl::deferred_init r; +#line 89 "pure2-autodiff-higher-order.cpp2" + double t {x + y}; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + +#line 94 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ + cpp2::impl::deferred_init r; +#line 95 "pure2-autodiff-higher-order.cpp2" + int i {}; // TODO: Handle as passive when type information on call side is available. + r.construct(x + y); + i = 2; + + static_cast(cpp2::move(i)); + return std::move(r.value()); } + +#line 102 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ + cpp2::impl::deferred_init r; +#line 103 "pure2-autodiff-higher-order.cpp2" + auto t {0.0}; + t = x + y; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + +#line 109 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ + cpp2::impl::deferred_init r; +#line 110 "pure2-autodiff-higher-order.cpp2" + double t {}; + t = x + y; + + r.construct(cpp2::move(t)); + return std::move(r.value()); } + +#line 116 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ + cpp2::impl::deferred_init r; +#line 117 "pure2-autodiff-higher-order.cpp2" + cpp2::impl::deferred_init t; + t.construct(x + y); + + r.construct(cpp2::move(t.value())); + return std::move(r.value()); } + +#line 123 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ + cpp2::impl::deferred_init r; +#line 124 "pure2-autodiff-higher-order.cpp2" + int i {0}; + + r.construct(x); + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + r.value() = r.value() + y; + }return std::move(r.value()); + } + +#line 132 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ + cpp2::impl::deferred_init r; +#line 133 "pure2-autodiff-higher-order.cpp2" + int i {0}; + + r.construct(x); + do { + r.value() = r.value() + y; + } while ( [&]{ + (i += 1) ; return true; }() && + cpp2::impl::cmp_less(i,2));return std::move(r.value()); + } + +#line 143 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ + cpp2::impl::deferred_init r; +#line 144 "pure2-autodiff-higher-order.cpp2" + std::vector v {}; + + CPP2_UFCS(push_back)(v, x); + CPP2_UFCS(push_back)(v, y); + + r.construct(0.0); + for ( + auto const& t : cpp2::move(v) ) + { + r.value() = r.value() + t; + }return std::move(r.value()); + } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0};r_d = x_d + y_d; @@ -409,25 +627,185 @@ auto temp_1_d {x_d - y_d}; return { std::move(r), std::move(r_d) }; } -#line 68 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::if_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_branch_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d; + r = x; + if (cpp2::impl::cmp_less(x,0.0)) { + r_d = y_d; + r = y; + } + else { + } + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::if_else_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_else_branch_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { + r_d = y_d; + r = y; + } + else { + r_d = x_d; + r = x; + } + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::direct_return_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> direct_return_d_ret{ + double r {}; + cpp2::taylor r_d {};r_d = x_d + y_d; + r = x + y; + return { std::move(r), std::move(r_d) }; } + + [[nodiscard]] auto ad_test::intermediate_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_var_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::taylor t_d {x_d + y_d}; + + double t {x + y}; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_passive_var_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i_d {}; + + int i {}; + r_d = x_d + y_d; + r = x + y; + i_d = { }; + i = 2; + static_cast(cpp2::move(i_d)); + static_cast(cpp2::move(i)); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_untyped_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto t_d {cpp2::taylor()}; + + auto t {0.0}; + t_d = x_d + y_d; + t = x + y; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_default_init_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::taylor t_d {}; + + double t {}; + t_d = x_d + y_d; + t = x + y; + r_d = cpp2::move(t_d); + r = cpp2::move(t); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_no_init_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::impl::deferred_init> t_d; + + cpp2::impl::deferred_init t; + t_d.construct(x_d + y_d); + t.construct(x + y); + r_d = cpp2::move(t_d.value()); + r = cpp2::move(t.value()); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> while_loop_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i_d {}; + + int i {0}; + r_d = x_d; + r = x; + for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { + r_d = r_d + y_d; + r = r + y; + } + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::do_while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> do_while_loop_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i_d {}; + + int i {0}; + r_d = x_d; + r = x; + do { + r_d = r_d + y_d; + r = r + y; + } + while ( [&]{ + (i += 1) + ; return true; }() && + cpp2::impl::cmp_less(i,2) + ); + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::for_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> for_loop_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +std::vector> v_d {}; + + std::vector v {}; + CPP2_UFCS(push_back)(v, x); + CPP2_UFCS(push_back)(v_d, x_d); + CPP2_UFCS(push_back)(v, y); + CPP2_UFCS(push_back)(v_d, y_d); + r_d = { }; + r = 0.0; +{ +auto t_d_iter{CPP2_UFCS(begin)(cpp2::move(v_d))}; + for ( auto const& t : cpp2::move(v) ) { do { +{ +auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; + { + r_d = r_d + t_d; + r = r + t; + } +} + } + while (false); (++t_d_iter); } +} + return { std::move(r), std::move(r_d) }; + } + +#line 158 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 72 "pure2-autodiff-higher-order.cpp2" +#line 162 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 75 "pure2-autodiff-higher-order.cpp2" +#line 165 "pure2-autodiff-higher-order.cpp2" } -#line 77 "pure2-autodiff-higher-order.cpp2" +#line 167 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 80 "pure2-autodiff-higher-order.cpp2" +#line 170 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; @@ -446,17 +824,17 @@ auto main() -> int{ write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); -// write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); -// write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); -// write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); -// write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); -// write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); -// write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); -// write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); -// write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); -// write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); -// write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); -// write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 31cfcb1ec..bcdd140e2 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -137,6 +137,146 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + if_branch:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x; + if x < 0.0 + { + r = y; + } + return; + } + + if_else_branch:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + if x < 0.0 + { + r = y; + } + else + { + r = x; + } + return; + } + + direct_return:( + in x: double, + in y: double, + ) -> move double = + { + return x + y; + } + + intermediate_var:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: double = x + y; + r = t; + return; + } + + intermediate_passive_var:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = (); + r = x + y; + i = 2; + _ = i; + return; + } + + intermediate_untyped:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: _ = 0.0; + t = x + y; + r = t; + return; + } + + intermediate_default_init:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: double = (); + t = x + y; + r = t; + return; + } + + intermediate_no_init:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: double; + t = x + y; + r = t; + return; + } + + while_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = 0; + r = x; + while i < 2 + next (i += 1) + { + r = r + y; + } + return; + } + + do_while_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + i: int = 0; + r = x; + do + { + r = r + y; + } + next (i += 1) + while i < 2; + return; + } + + for_loop:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + v: std::vector = (); + v.push_back(x); + v.push_back(y); + r = 0.0; + for v + do (in t: _) + { + r = r + t; + } + return; + } + add_1_d:( in x: double, in x_d: cpp2::taylor, @@ -376,6 +516,241 @@ ad_test:/* @autodiff<"order=6"> @print */ type = r = sin(temp_1); return; } + + if_branch_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + r_d = x_d; + r = x; + if x < 0.0 + { + r_d = y_d; + r = y; + } + else + { + } + return; + } + + if_else_branch_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + if x < 0.0 + { + r_d = y_d; + r = y; + } + else + { + r_d = x_d; + r = x; + } + return; + } + + direct_return_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = (), + out r_d: cpp2::taylor = (), + ) = + { + r_d = x_d + y_d; + r = x + y; + return; + } + + intermediate_var_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: cpp2::taylor = x_d + y_d; + t: double = x + y; + r_d = t_d; + r = t; + return; + } + + intermediate_passive_var_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + i_d: int = (); + i: int = (); + r_d = x_d + y_d; + r = x + y; + i_d = (); + i = 2; + _ = i_d; + _ = i; + return; + } + + intermediate_untyped_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: _ = cpp2::taylor(); + t: _ = 0.0; + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + + intermediate_default_init_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: cpp2::taylor = (); + t: double = (); + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + + intermediate_no_init_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: cpp2::taylor; + t: double; + t_d = x_d + y_d; + t = x + y; + r_d = t_d; + r = t; + return; + } + + while_loop_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + i_d: int = (); + i: int = 0; + r_d = x_d; + r = x; + while i < 2 + next (i += 1) + { + r_d = r_d + y_d; + r = r + y; + } + return; + } + + do_while_loop_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + i_d: int = (); + i: int = 0; + r_d = x_d; + r = x; + do + { + r_d = r_d + y_d; + r = r + y; + } + next (i += 1) + while i < 2; + return; + } + + for_loop_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + v_d: std::vector> = (); + v: std::vector = (); + v.push_back(x); + v_d.push_back(x_d); + v.push_back(y); + v_d.push_back(y_d); + r_d = (); + r = 0.0; + (copy t_d_iter: _ = v_d.begin(), ) + for v + next (t_d_iter++) + do (in t: _) + { + (in t_d: _ = t_d_iter*, ) + { + r_d = r_d + t_d; + r = r + t; + } + } + return; + } } ok (all Cpp2, passes safety checks) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 9721a0584..337e7a84a 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -713,7 +713,7 @@ int i_d {}; [[nodiscard]] auto ad_test::intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_d_ret{ double r {0.0}; double r_d {0.0}; -auto t_d {0.0}; +auto t_d {double()}; auto t {0.0}; t_d = x_d + y_d; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 831fdd03b..fcfb5ed38 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -626,7 +626,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - t_d: _ = 0.0; + t_d: _ = double(); t: _ = 0.0; t_d = x_d + y_d; t = x + y; diff --git a/source/reflect.h b/source/reflect.h index 16d19f2d0..3c31443d9 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -123,80 +123,80 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4504 "reflect.h2" +#line 4507 "reflect.h2" class autodiff_stmt_handler; -#line 4887 "reflect.h2" +#line 4890 "reflect.h2" class expression_flags; -#line 4903 "reflect.h2" +#line 4906 "reflect.h2" class regex_token; -#line 4930 "reflect.h2" +#line 4933 "reflect.h2" class regex_token_check; -#line 4951 "reflect.h2" +#line 4954 "reflect.h2" class regex_token_code; -#line 4972 "reflect.h2" +#line 4975 "reflect.h2" class regex_token_empty; -#line 4990 "reflect.h2" +#line 4993 "reflect.h2" class regex_token_list; -#line 5042 "reflect.h2" +#line 5045 "reflect.h2" class parse_context_group_state; -#line 5103 "reflect.h2" +#line 5106 "reflect.h2" class parse_context_branch_reset_state; -#line 5146 "reflect.h2" +#line 5149 "reflect.h2" class parse_context; -#line 5547 "reflect.h2" +#line 5550 "reflect.h2" class generation_function_context; -#line 5565 "reflect.h2" +#line 5568 "reflect.h2" class generation_context; -#line 5764 "reflect.h2" +#line 5767 "reflect.h2" class alternative_token; -#line 5779 "reflect.h2" +#line 5782 "reflect.h2" class alternative_token_gen; -#line 5844 "reflect.h2" +#line 5847 "reflect.h2" class any_token; -#line 5861 "reflect.h2" +#line 5864 "reflect.h2" class atomic_group_token; -#line 5891 "reflect.h2" +#line 5894 "reflect.h2" class char_token; -#line 6006 "reflect.h2" +#line 6009 "reflect.h2" class class_token; -#line 6230 "reflect.h2" +#line 6233 "reflect.h2" class group_ref_token; -#line 6367 "reflect.h2" +#line 6370 "reflect.h2" class group_token; -#line 6714 "reflect.h2" +#line 6717 "reflect.h2" class lookahead_lookbehind_token; -#line 6809 "reflect.h2" +#line 6812 "reflect.h2" class range_token; -#line 6966 "reflect.h2" +#line 6969 "reflect.h2" class special_range_token; -#line 7052 "reflect.h2" +#line 7055 "reflect.h2" template class regex_generator; -#line 7309 "reflect.h2" +#line 7312 "reflect.h2" } } @@ -1827,111 +1827,111 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4502 "reflect.h2" +#line 4505 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4508 "reflect.h2" +#line 4511 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4517 "reflect.h2" +#line 4520 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4522 "reflect.h2" +#line 4525 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4527 "reflect.h2" +#line 4530 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4545 "reflect.h2" +#line 4548 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4550 "reflect.h2" +#line 4553 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4555 "reflect.h2" +#line 4558 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4560 "reflect.h2" +#line 4563 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4568 "reflect.h2" +#line 4571 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4584 "reflect.h2" +#line 4587 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4631 "reflect.h2" +#line 4634 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4642 "reflect.h2" +#line 4645 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4670 "reflect.h2" +#line 4673 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4675 "reflect.h2" +#line 4678 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4679 "reflect.h2" +#line 4682 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4683 "reflect.h2" +#line 4686 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4687 "reflect.h2" +#line 4690 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4691 "reflect.h2" +#line 4694 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4695 "reflect.h2" +#line 4698 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4699 "reflect.h2" +#line 4702 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4703 "reflect.h2" +#line 4706 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4707 "reflect.h2" +#line 4710 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4711 "reflect.h2" +#line 4714 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4715 "reflect.h2" +#line 4718 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4719 "reflect.h2" +#line 4722 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4723 "reflect.h2" +#line 4726 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4728 "reflect.h2" +#line 4731 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4757 "reflect.h2" +#line 4760 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4761 "reflect.h2" +#line 4764 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4883 "reflect.h2" +#line 4886 "reflect.h2" using error_func = std::function x)>; -#line 4887 "reflect.h2" +#line 4890 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1966,20 +1966,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4895 "reflect.h2" +#line 4898 "reflect.h2" }; -#line 4903 "reflect.h2" +#line 4906 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4911 "reflect.h2" +#line 4914 "reflect.h2" public: explicit regex_token(); -#line 4916 "reflect.h2" +#line 4919 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1991,103 +1991,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4922 "reflect.h2" +#line 4925 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4928 "reflect.h2" +#line 4931 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4934 "reflect.h2" +#line 4937 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4941 "reflect.h2" +#line 4944 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4945 "reflect.h2" +#line 4948 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4946 "reflect.h2" +#line 4949 "reflect.h2" }; -#line 4949 "reflect.h2" +#line 4952 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4955 "reflect.h2" +#line 4958 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4962 "reflect.h2" +#line 4965 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4966 "reflect.h2" +#line 4969 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4967 "reflect.h2" +#line 4970 "reflect.h2" }; -#line 4970 "reflect.h2" +#line 4973 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4976 "reflect.h2" +#line 4979 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4980 "reflect.h2" +#line 4983 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4984 "reflect.h2" +#line 4987 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4985 "reflect.h2" +#line 4988 "reflect.h2" }; -#line 4988 "reflect.h2" +#line 4991 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4994 "reflect.h2" +#line 4997 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5001 "reflect.h2" +#line 5004 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5007 "reflect.h2" +#line 5010 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5013 "reflect.h2" +#line 5016 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5021 "reflect.h2" +#line 5024 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2095,10 +2095,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5033 "reflect.h2" +#line 5036 "reflect.h2" }; -#line 5036 "reflect.h2" +#line 5039 "reflect.h2" // // Parse and generation context. // @@ -2114,33 +2114,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5056 "reflect.h2" +#line 5059 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5063 "reflect.h2" +#line 5066 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5075 "reflect.h2" +#line 5078 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5080 "reflect.h2" +#line 5083 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5084 "reflect.h2" +#line 5087 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5098 "reflect.h2" +#line 5101 "reflect.h2" }; -#line 5101 "reflect.h2" +#line 5104 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2153,25 +2153,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5119 "reflect.h2" +#line 5122 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5125 "reflect.h2" +#line 5128 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5132 "reflect.h2" +#line 5135 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5139 "reflect.h2" +#line 5142 "reflect.h2" }; -#line 5142 "reflect.h2" +#line 5145 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2187,7 +2187,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5158 "reflect.h2" +#line 5161 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2195,64 +2195,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5169 "reflect.h2" +#line 5172 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5182 "reflect.h2" +#line 5185 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5190 "reflect.h2" +#line 5193 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5194 "reflect.h2" +#line 5197 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5198 "reflect.h2" +#line 5201 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5210 "reflect.h2" +#line 5213 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5217 "reflect.h2" +#line 5220 "reflect.h2" public: auto next_alternative() & -> void; -#line 5223 "reflect.h2" +#line 5226 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5229 "reflect.h2" +#line 5232 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5233 "reflect.h2" +#line 5236 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5244 "reflect.h2" +#line 5247 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5248 "reflect.h2" +#line 5251 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5254 "reflect.h2" +#line 5257 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5258 "reflect.h2" +#line 5261 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5265 "reflect.h2" +#line 5268 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5276 "reflect.h2" +#line 5279 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2260,51 +2260,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5320 "reflect.h2" +#line 5323 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5332 "reflect.h2" +#line 5335 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5345 "reflect.h2" +#line 5348 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5368 "reflect.h2" +#line 5371 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5385 "reflect.h2" +#line 5388 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5406 "reflect.h2" +#line 5409 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5416 "reflect.h2" +#line 5419 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5420 "reflect.h2" +#line 5423 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5476 "reflect.h2" +#line 5479 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5515 "reflect.h2" +#line 5518 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5530 "reflect.h2" +#line 5533 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2316,10 +2316,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5541 "reflect.h2" +#line 5544 "reflect.h2" }; -#line 5544 "reflect.h2" +#line 5547 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2329,16 +2329,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5558 "reflect.h2" +#line 5561 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5561 "reflect.h2" +#line 5564 "reflect.h2" }; -#line 5564 "reflect.h2" +#line 5567 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2358,68 +2358,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5586 "reflect.h2" +#line 5589 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5592 "reflect.h2" +#line 5595 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5601 "reflect.h2" +#line 5604 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5612 "reflect.h2" +#line 5615 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5619 "reflect.h2" +#line 5622 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5639 "reflect.h2" +#line 5642 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5649 "reflect.h2" +#line 5652 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5672 "reflect.h2" +#line 5675 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5680 "reflect.h2" +#line 5683 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5684 "reflect.h2" +#line 5687 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5690 "reflect.h2" +#line 5693 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5696 "reflect.h2" +#line 5699 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5706 "reflect.h2" +#line 5709 "reflect.h2" public: auto finish_context() & -> void; -#line 5714 "reflect.h2" +#line 5717 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5720 "reflect.h2" +#line 5723 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5724 "reflect.h2" +#line 5727 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5728 "reflect.h2" +#line 5731 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5752 "reflect.h2" +#line 5755 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2427,7 +2427,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5758 "reflect.h2" +#line 5761 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2447,27 +2447,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5777 "reflect.h2" +#line 5780 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5783 "reflect.h2" +#line 5786 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5790 "reflect.h2" +#line 5793 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5807 "reflect.h2" +#line 5810 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5814 "reflect.h2" +#line 5817 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5827 "reflect.h2" +#line 5830 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2475,19 +2475,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5839 "reflect.h2" +#line 5842 "reflect.h2" }; -#line 5842 "reflect.h2" +#line 5845 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5848 "reflect.h2" +#line 5851 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5852 "reflect.h2" +#line 5855 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2495,7 +2495,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5857 "reflect.h2" +#line 5860 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2503,17 +2503,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5865 "reflect.h2" +#line 5868 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5876 "reflect.h2" +#line 5879 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5884 "reflect.h2" +#line 5887 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2521,7 +2521,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5887 "reflect.h2" +#line 5890 "reflect.h2" }; // Regex syntax: a @@ -2529,34 +2529,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5895 "reflect.h2" +#line 5898 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5904 "reflect.h2" +#line 5907 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5910 "reflect.h2" +#line 5913 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5914 "reflect.h2" +#line 5917 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5937 "reflect.h2" +#line 5940 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5958 "reflect.h2" +#line 5961 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5976 "reflect.h2" +#line 5979 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5991 "reflect.h2" +#line 5994 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5997 "reflect.h2" +#line 6000 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2564,33 +2564,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6001 "reflect.h2" +#line 6004 "reflect.h2" }; -#line 6004 "reflect.h2" +#line 6007 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6010 "reflect.h2" +#line 6013 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6022 "reflect.h2" +#line 6025 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6148 "reflect.h2" +#line 6151 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6157 "reflect.h2" +#line 6160 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6162 "reflect.h2" +#line 6165 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2598,20 +2598,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6169 "reflect.h2" +#line 6172 "reflect.h2" }; -#line 6172 "reflect.h2" +#line 6175 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6213 "reflect.h2" +#line 6216 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6224 "reflect.h2" +#line 6227 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2621,20 +2621,20 @@ class class_token class group_ref_token : public regex_token { -#line 6234 "reflect.h2" +#line 6237 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6246 "reflect.h2" +#line 6249 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6347 "reflect.h2" +#line 6350 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6351 "reflect.h2" +#line 6354 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2642,10 +2642,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6354 "reflect.h2" +#line 6357 "reflect.h2" }; -#line 6357 "reflect.h2" +#line 6360 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2659,29 +2659,29 @@ class group_ref_token class group_token : public regex_token { -#line 6371 "reflect.h2" +#line 6374 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6393 "reflect.h2" +#line 6396 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6407 "reflect.h2" +#line 6410 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6566 "reflect.h2" +#line 6569 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6574 "reflect.h2" +#line 6577 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6592 "reflect.h2" +#line 6595 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6623 "reflect.h2" +#line 6626 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2690,25 +2690,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6630 "reflect.h2" +#line 6633 "reflect.h2" }; -#line 6633 "reflect.h2" +#line 6636 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6674 "reflect.h2" +#line 6677 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6694 "reflect.h2" +#line 6697 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6710 "reflect.h2" +#line 6713 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2716,20 +2716,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6718 "reflect.h2" +#line 6721 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6727 "reflect.h2" +#line 6730 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6738 "reflect.h2" +#line 6741 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6745 "reflect.h2" +#line 6748 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2737,26 +2737,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6748 "reflect.h2" +#line 6751 "reflect.h2" }; -#line 6751 "reflect.h2" +#line 6754 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6779 "reflect.h2" +#line 6782 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6807 "reflect.h2" +#line 6810 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6813 "reflect.h2" +#line 6816 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2766,22 +2766,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6893 "reflect.h2" +#line 6896 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6905 "reflect.h2" +#line 6908 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6918 "reflect.h2" +#line 6921 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6937 "reflect.h2" +#line 6940 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6947 "reflect.h2" +#line 6950 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6958 "reflect.h2" +#line 6961 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2789,16 +2789,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6961 "reflect.h2" +#line 6964 "reflect.h2" }; -#line 6964 "reflect.h2" +#line 6967 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6970 "reflect.h2" +#line 6973 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2807,7 +2807,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7000 "reflect.h2" +#line 7003 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2816,14 +2816,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7022 "reflect.h2" +#line 7025 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7044 "reflect.h2" +#line 7047 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2844,24 +2844,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7067 "reflect.h2" +#line 7070 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7102 "reflect.h2" +#line 7105 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7116 "reflect.h2" +#line 7119 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7128 "reflect.h2" +#line 7131 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7183 "reflect.h2" +#line 7186 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2872,7 +2872,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7309 "reflect.h2" +#line 7312 "reflect.h2" } } @@ -8015,10 +8015,13 @@ auto i{0}; } } else {if (CPP2_UFCS(is_literal)(primary)) { - // TODO: Determine propre zero initializer from type of literal. + auto literal_str {CPP2_UFCS(to_string)(primary)}; + std::string ad_init {"()"}; + + // TODO: Determine propre zero initializer from type of literal. if (declare_d == ":" || declare_d == ": _") { - ad_init = "0.0"; + ad_init = CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; } gen_lhs_assignment(CPP2_UFCS(to_string)(primary), cpp2::move(ad_init)); } @@ -8030,26 +8033,26 @@ auto i{0}; }}}} } -#line 4512 "reflect.h2" +#line 4515 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4515 "reflect.h2" +#line 4518 "reflect.h2" } -#line 4517 "reflect.h2" +#line 4520 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4522 "reflect.h2" +#line 4525 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4527 "reflect.h2" +#line 4530 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8067,22 +8070,22 @@ auto i{0}; } } -#line 4545 "reflect.h2" +#line 4548 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4550 "reflect.h2" +#line 4553 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4555 "reflect.h2" +#line 4558 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4560 "reflect.h2" +#line 4563 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8090,7 +8093,7 @@ auto i{0}; diff += "}\n"; } -#line 4568 "reflect.h2" +#line 4571 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8106,7 +8109,7 @@ auto i{0}; } } -#line 4584 "reflect.h2" +#line 4587 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8153,7 +8156,7 @@ auto i{0}; }} } -#line 4631 "reflect.h2" +#line 4634 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8165,7 +8168,7 @@ auto i{0}; } } -#line 4642 "reflect.h2" +#line 4645 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8194,79 +8197,79 @@ auto i{0}; } } -#line 4670 "reflect.h2" +#line 4673 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4675 "reflect.h2" +#line 4678 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4679 "reflect.h2" +#line 4682 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4683 "reflect.h2" +#line 4686 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4687 "reflect.h2" +#line 4690 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4691 "reflect.h2" +#line 4694 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4695 "reflect.h2" +#line 4698 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4699 "reflect.h2" +#line 4702 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4703 "reflect.h2" +#line 4706 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4707 "reflect.h2" +#line 4710 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4711 "reflect.h2" +#line 4714 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4715 "reflect.h2" +#line 4718 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4719 "reflect.h2" +#line 4722 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4723 "reflect.h2" +#line 4726 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4728 "reflect.h2" +#line 4731 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8275,7 +8278,7 @@ auto i{0}; { auto i{0}; -#line 4735 "reflect.h2" +#line 4738 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8289,7 +8292,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4747 "reflect.h2" +#line 4750 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8300,13 +8303,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4757 "reflect.h2" +#line 4760 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4763 "reflect.h2" +#line 4766 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8371,7 +8374,7 @@ auto autodiff(meta::type_declaration& t) -> void diff += "r, r" + cpp2::to_string(suffix) + ", "; } else { - diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r" + cpp2::to_string(suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), "; + diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r" + cpp2::to_string(suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(get_unnamed_return_type)(mf))) + " = (), "; } } else { @@ -8390,10 +8393,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } -#line 4847 "reflect.h2" +#line 4850 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4850 "reflect.h2" +#line 4853 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8503,7 +8506,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4869 "reflect.h2" +#line 4872 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8519,11 +8522,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4885 "reflect.h2" +#line 4888 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4889 "reflect.h2" +#line 4892 "reflect.h2" // mod: i // mod: m // mod: s @@ -8531,116 +8534,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4898 "reflect.h2" +#line 4901 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4907 "reflect.h2" +#line 4910 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4909 "reflect.h2" +#line 4912 "reflect.h2" } -#line 4911 "reflect.h2" +#line 4914 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4913 "reflect.h2" +#line 4916 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4919 "reflect.h2" +#line 4922 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4920 "reflect.h2" +#line 4923 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4921 "reflect.h2" +#line 4924 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4936 "reflect.h2" +#line 4939 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4939 "reflect.h2" +#line 4942 "reflect.h2" } -#line 4941 "reflect.h2" +#line 4944 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4945 "reflect.h2" +#line 4948 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4957 "reflect.h2" +#line 4960 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4960 "reflect.h2" +#line 4963 "reflect.h2" } -#line 4962 "reflect.h2" +#line 4965 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4966 "reflect.h2" +#line 4969 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4976 "reflect.h2" +#line 4979 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4978 "reflect.h2" +#line 4981 "reflect.h2" } -#line 4980 "reflect.h2" +#line 4983 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4984 "reflect.h2" +#line 4987 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4996 "reflect.h2" +#line 4999 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 4999 "reflect.h2" +#line 5002 "reflect.h2" } -#line 5001 "reflect.h2" +#line 5004 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5007 "reflect.h2" +#line 5010 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5013 "reflect.h2" +#line 5016 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8649,7 +8652,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5021 "reflect.h2" +#line 5024 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8665,7 +8668,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5049 "reflect.h2" +#line 5052 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8673,14 +8676,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5057 "reflect.h2" +#line 5060 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5064 "reflect.h2" +#line 5067 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8692,15 +8695,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5076 "reflect.h2" +#line 5079 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5081 "reflect.h2" +#line 5084 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5085 "reflect.h2" +#line 5088 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8721,7 +8724,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5111 "reflect.h2" +#line 5114 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8730,20 +8733,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5120 "reflect.h2" +#line 5123 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5126 "reflect.h2" +#line 5129 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5133 "reflect.h2" +#line 5136 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8758,16 +8761,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5163 "reflect.h2" +#line 5166 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5167 "reflect.h2" +#line 5170 "reflect.h2" } -#line 5173 "reflect.h2" +#line 5176 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8777,7 +8780,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5183 "reflect.h2" +#line 5186 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8785,17 +8788,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5190 "reflect.h2" +#line 5193 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5194 "reflect.h2" +#line 5197 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5201 "reflect.h2" +#line 5204 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8805,7 +8808,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5210 "reflect.h2" +#line 5213 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8813,24 +8816,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5217 "reflect.h2" +#line 5220 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5225 "reflect.h2" +#line 5228 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5229 "reflect.h2" +#line 5232 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5233 "reflect.h2" +#line 5236 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8842,22 +8845,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5244 "reflect.h2" +#line 5247 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5250 "reflect.h2" +#line 5253 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5254 "reflect.h2" +#line 5257 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5258 "reflect.h2" +#line 5261 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8865,7 +8868,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5265 "reflect.h2" +#line 5268 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8877,10 +8880,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5278 "reflect.h2" +#line 5281 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5281 "reflect.h2" +#line 5284 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8920,7 +8923,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5321 "reflect.h2" +#line 5324 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8932,14 +8935,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5332 "reflect.h2" +#line 5335 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5333 "reflect.h2" +#line 5336 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5334 "reflect.h2" +#line 5337 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5336 "reflect.h2" +#line 5339 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8949,10 +8952,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5345 "reflect.h2" +#line 5348 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5347 "reflect.h2" +#line 5350 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8974,14 +8977,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5368 "reflect.h2" +#line 5371 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5369 "reflect.h2" +#line 5372 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5370 "reflect.h2" +#line 5373 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5372 "reflect.h2" +#line 5375 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8995,7 +8998,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5385 "reflect.h2" +#line 5388 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9017,7 +9020,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5406 "reflect.h2" +#line 5409 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9028,12 +9031,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5416 "reflect.h2" +#line 5419 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5417 "reflect.h2" +#line 5420 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5422 "reflect.h2" +#line 5425 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9088,7 +9091,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5476 "reflect.h2" +#line 5479 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9128,7 +9131,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5515 "reflect.h2" +#line 5518 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9144,21 +9147,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5532 "reflect.h2" +#line 5535 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5533 "reflect.h2" +#line 5536 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5534 "reflect.h2" +#line 5537 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5536 "reflect.h2" +#line 5539 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5551 "reflect.h2" +#line 5554 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9166,7 +9169,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5558 "reflect.h2" +#line 5561 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9176,22 +9179,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5576 "reflect.h2" +#line 5579 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5581 "reflect.h2" +#line 5584 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5587 "reflect.h2" +#line 5590 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5593 "reflect.h2" +#line 5596 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9200,7 +9203,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5601 "reflect.h2" +#line 5604 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9212,7 +9215,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5612 "reflect.h2" +#line 5615 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9220,7 +9223,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5619 "reflect.h2" +#line 5622 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9241,7 +9244,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5640 "reflect.h2" +#line 5643 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9251,7 +9254,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5650 "reflect.h2" +#line 5653 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9274,33 +9277,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5674 "reflect.h2" +#line 5677 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5680 "reflect.h2" +#line 5683 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5684 "reflect.h2" +#line 5687 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5690 "reflect.h2" +#line 5693 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5698 "reflect.h2" +#line 5701 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9309,7 +9312,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5706 "reflect.h2" +#line 5709 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9318,22 +9321,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5716 "reflect.h2" +#line 5719 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5720 "reflect.h2" +#line 5723 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5724 "reflect.h2" +#line 5727 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5728 "reflect.h2" +#line 5731 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9357,18 +9360,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5753 "reflect.h2" +#line 5756 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5768 "reflect.h2" +#line 5771 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5770 "reflect.h2" +#line 5773 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9379,15 +9382,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5785 "reflect.h2" +#line 5788 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5788 "reflect.h2" +#line 5791 "reflect.h2" } -#line 5790 "reflect.h2" +#line 5793 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9405,7 +9408,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5807 "reflect.h2" +#line 5810 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9413,7 +9416,7 @@ generation_function_context::generation_function_context(){} } } -#line 5814 "reflect.h2" +#line 5817 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9427,7 +9430,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5827 "reflect.h2" +#line 5830 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9443,14 +9446,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5848 "reflect.h2" +#line 5851 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5850 "reflect.h2" +#line 5853 "reflect.h2" } -#line 5852 "reflect.h2" +#line 5855 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9459,11 +9462,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5867 "reflect.h2" +#line 5870 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5869 "reflect.h2" +#line 5872 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9471,7 +9474,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5876 "reflect.h2" +#line 5879 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9480,37 +9483,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5884 "reflect.h2" +#line 5887 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5898 "reflect.h2" +#line 5901 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5902 "reflect.h2" +#line 5905 "reflect.h2" } -#line 5904 "reflect.h2" +#line 5907 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5908 "reflect.h2" +#line 5911 "reflect.h2" } -#line 5910 "reflect.h2" +#line 5913 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5914 "reflect.h2" +#line 5917 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9519,14 +9522,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5920 "reflect.h2" +#line 5923 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5925 "reflect.h2" +#line 5928 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9539,7 +9542,7 @@ size_t i{0}; } } -#line 5937 "reflect.h2" +#line 5940 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9561,7 +9564,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5958 "reflect.h2" +#line 5961 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9580,7 +9583,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5976 "reflect.h2" +#line 5979 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9596,14 +9599,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5991 "reflect.h2" +#line 5994 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 5997 "reflect.h2" +#line 6000 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9611,19 +9614,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6014 "reflect.h2" +#line 6017 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6015 "reflect.h2" +#line 6018 "reflect.h2" { -#line 6020 "reflect.h2" +#line 6023 "reflect.h2" } -#line 6023 "reflect.h2" +#line 6026 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9749,7 +9752,7 @@ size_t i{0}; ); } -#line 6148 "reflect.h2" +#line 6151 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9759,13 +9762,13 @@ size_t i{0}; ); } -#line 6157 "reflect.h2" +#line 6160 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6162 "reflect.h2" +#line 6165 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9776,12 +9779,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6174 "reflect.h2" +#line 6177 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6179 "reflect.h2" +#line 6182 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9815,7 +9818,7 @@ size_t i{0}; } -#line 6215 "reflect.h2" +#line 6218 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9824,19 +9827,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6238 "reflect.h2" +#line 6241 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6239 "reflect.h2" +#line 6242 "reflect.h2" { -#line 6244 "reflect.h2" +#line 6247 "reflect.h2" } -#line 6246 "reflect.h2" +#line 6249 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9938,19 +9941,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6347 "reflect.h2" +#line 6350 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6351 "reflect.h2" +#line 6354 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6375 "reflect.h2" +#line 6378 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9969,7 +9972,7 @@ size_t i{0}; return r; } -#line 6393 "reflect.h2" +#line 6396 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9984,7 +9987,7 @@ size_t i{0}; return r; } -#line 6407 "reflect.h2" +#line 6410 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10144,7 +10147,7 @@ size_t i{0}; } } -#line 6566 "reflect.h2" +#line 6569 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10153,7 +10156,7 @@ size_t i{0}; return r; } -#line 6574 "reflect.h2" +#line 6577 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10172,7 +10175,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6592 "reflect.h2" +#line 6595 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10204,7 +10207,7 @@ size_t i{0}; } } -#line 6623 "reflect.h2" +#line 6626 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10215,7 +10218,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6635 "reflect.h2" +#line 6638 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10254,7 +10257,7 @@ size_t i{0}; return r; } -#line 6676 "reflect.h2" +#line 6679 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10272,7 +10275,7 @@ size_t i{0}; }} } -#line 6696 "reflect.h2" +#line 6699 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10286,16 +10289,16 @@ size_t i{0}; } } -#line 6722 "reflect.h2" +#line 6725 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6725 "reflect.h2" +#line 6728 "reflect.h2" } -#line 6727 "reflect.h2" +#line 6730 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10307,7 +10310,7 @@ size_t i{0}; } } -#line 6738 "reflect.h2" +#line 6741 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10315,14 +10318,14 @@ size_t i{0}; return r; } -#line 6745 "reflect.h2" +#line 6748 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6753 "reflect.h2" +#line 6756 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10348,7 +10351,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6781 "reflect.h2" +#line 6784 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10374,11 +10377,11 @@ size_t i{0}; return r; } -#line 6818 "reflect.h2" +#line 6821 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6820 "reflect.h2" +#line 6823 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10452,7 +10455,7 @@ size_t i{0}; return nullptr; } -#line 6893 "reflect.h2" +#line 6896 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10465,7 +10468,7 @@ size_t i{0}; }} } -#line 6905 "reflect.h2" +#line 6908 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10479,7 +10482,7 @@ size_t i{0}; }} } -#line 6918 "reflect.h2" +#line 6921 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10499,7 +10502,7 @@ size_t i{0}; return r; } -#line 6937 "reflect.h2" +#line 6940 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10510,7 +10513,7 @@ size_t i{0}; return r; } -#line 6947 "reflect.h2" +#line 6950 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10522,14 +10525,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6958 "reflect.h2" +#line 6961 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6970 "reflect.h2" +#line 6973 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10553,7 +10556,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6994 "reflect.h2" +#line 6997 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10563,7 +10566,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7006 "reflect.h2" +#line 7009 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10579,7 +10582,7 @@ size_t i{0}; } } -#line 7026 "reflect.h2" +#line 7029 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10597,15 +10600,15 @@ size_t i{0}; }} } -#line 7062 "reflect.h2" +#line 7065 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7065 "reflect.h2" +#line 7068 "reflect.h2" } -#line 7067 "reflect.h2" +#line 7070 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10641,7 +10644,7 @@ size_t i{0}; return source; } -#line 7102 "reflect.h2" +#line 7105 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10657,7 +10660,7 @@ size_t i{0}; } } -#line 7118 "reflect.h2" +#line 7121 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10666,7 +10669,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10721,7 +10724,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7187 "reflect.h2" +#line 7190 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10843,7 +10846,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7309 "reflect.h2" +#line 7312 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index e4cfc14f6..d5ee00306 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4485,10 +4485,13 @@ autodiff_expression_handler: type = { } } else if primary.is_literal() { - // TODO: Determine propre zero initializer from type of literal. + literal_str := primary.to_string(); + ad_init : std::string = "()"; + + // TODO: Determine propre zero initializer from type of literal. if declare_d == ":" || declare_d == ": _" { - ad_init = "0.0"; + ad_init = ctx*.get_ad_type("double") + "()"; } gen_lhs_assignment(primary.to_string(), ad_init); } @@ -4824,7 +4827,7 @@ autodiff: (inout t: meta::type_declaration) = diff += "r, r(suffix)$, "; } else { - diff += "r: (mf.get_unnamed_return_type())$ = (), r(suffix)$: (mf.get_unnamed_return_type())$ = (), "; + diff += "r: (mf.get_unnamed_return_type())$ = (), r(suffix)$: (ad_ctx.get_ad_type(mf.get_unnamed_return_type()))$ = (), "; } } else { From 364d13fe60c968cede7f7024b218ec21b8e8b3b0 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 15 Aug 2025 10:41:50 +0200 Subject: [PATCH 27/54] Declaration lookup and lookup of function return name. --- .../pure2-autodiff-higher-order.cpp2 | 4 +- regression-tests/pure2-autodiff.cpp2 | 4 +- .../pure2-autodiff-higher-order.cpp | 20 +- .../pure2-autodiff-higher-order.cpp2.output | 16 +- .../test-results/pure2-autodiff.cpp | 20 +- .../test-results/pure2-autodiff.cpp2.output | 16 +- source/reflect.h | 1211 +++++++++-------- source/reflect.h2 | 97 +- 8 files changed, 809 insertions(+), 579 deletions(-) diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index bdfec488f..760704ea0 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -52,8 +52,8 @@ ad_test: @autodiff<"order=6"> @print type = { r = x + x * y; } - func: (x: double, y: double) -> (r: double) = { - r = x + y; + func: (x: double, y: double) -> (ret: double) = { + ret = x + y; } func_call: (x: double, y: double) -> (r: double) = { diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 1b78c2c2d..cfdd71f40 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -49,8 +49,8 @@ ad_test: @autodiff @print type = { r = x + x * y; } - func: (x: double, y: double) -> (r: double) = { - r = x + y; + func: (x: double, y: double) -> (ret: double) = { + ret = x + y; } func_call: (x: double, y: double) -> (r: double) = { diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index c1e64eb9e..6dede562f 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -199,7 +199,7 @@ struct add_mul_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret; -struct func_d_ret { double r; cpp2::taylor r_d; }; +struct func_d_ret { double ret; cpp2::taylor ret_d; }; public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret; @@ -358,10 +358,10 @@ auto main() -> int; #line 55 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ - cpp2::impl::deferred_init r; + cpp2::impl::deferred_init ret; #line 56 "pure2-autodiff-higher-order.cpp2" - r.construct(x + y); - return std::move(r.value()); } + ret.construct(x + y); + return std::move(ret.value()); } #line 59 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ @@ -597,10 +597,10 @@ auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; } [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d + y_d; - r = x + y; - return { std::move(r), std::move(r_d) }; + double ret {0.0}; + cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; + ret = x + y; + return { std::move(ret), std::move(ret_d) }; } [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret{ @@ -608,9 +608,9 @@ auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; cpp2::taylor r_d {0.0}; auto temp_2 {func_d(x, x_d, y, y_d)}; - auto temp_1 {temp_2.r}; + auto temp_1 {temp_2.ret}; - auto temp_1_d {cpp2::move(temp_2).r_d}; + auto temp_1_d {cpp2::move(temp_2).ret_d}; r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index bcdd140e2..7e4c57da7 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -113,9 +113,9 @@ ad_test:/* @autodiff<"order=6"> @print */ type = func:( in x: double, in y: double, - ) -> (out r: double, ) = + ) -> (out ret: double, ) = { - r = x + y; + ret = x + y; return; } @@ -473,12 +473,12 @@ ad_test:/* @autodiff<"order=6"> @print */ type = in y: double, in y_d: cpp2::taylor, ) -> ( - out r: double = 0.0, - out r_d: cpp2::taylor = 0.0, + out ret: double = 0.0, + out ret_d: cpp2::taylor = 0.0, ) = { - r_d = x_d + y_d; - r = x + y; + ret_d = x_d + y_d; + ret = x + y; return; } @@ -493,8 +493,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = ) = { temp_2: _ = func_d(x, x_d, y, y_d); - temp_1: _ = temp_2.r; - temp_1_d: _ = temp_2.r_d; + temp_1: _ = temp_2.ret; + temp_1_d: _ = temp_2.ret_d; r_d = x_d.mul(temp_1_d, x, temp_1); r = x * temp_1; return; diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 337e7a84a..1cc062ec2 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -198,7 +198,7 @@ struct add_mul_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret; -struct func_d_ret { double r; double r_d; }; +struct func_d_ret { double ret; double ret_d; }; public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret; @@ -383,10 +383,10 @@ auto main() -> int; #line 52 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ - cpp2::impl::deferred_init r; + cpp2::impl::deferred_init ret; #line 53 "pure2-autodiff.cpp2" - r.construct(x + y); - return std::move(r.value()); } + ret.construct(x + y); + return std::move(ret.value()); } #line 56 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ @@ -622,10 +622,10 @@ auto temp_1_d {x * y_d + y * x_d}; } [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d; - r = x + y; - return { std::move(r), std::move(r_d) }; + double ret {0.0}; + double ret_d {0.0};ret_d = x_d + y_d; + ret = x + y; + return { std::move(ret), std::move(ret_d) }; } [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret{ @@ -633,9 +633,9 @@ auto temp_1_d {x * y_d + y * x_d}; double r_d {0.0}; auto temp_2 {func_d(x, x_d, y, y_d)}; - auto temp_1 {temp_2.r}; + auto temp_1 {temp_2.ret}; - auto temp_1_d {cpp2::move(temp_2).r_d}; + auto temp_1_d {cpp2::move(temp_2).ret_d}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index fcfb5ed38..b3a384df4 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -113,9 +113,9 @@ ad_test:/* @autodiff @print */ type = func:( in x: double, in y: double, - ) -> (out r: double, ) = + ) -> (out ret: double, ) = { - r = x + y; + ret = x + y; return; } @@ -473,12 +473,12 @@ ad_test:/* @autodiff @print */ type = in y: double, in y_d: double, ) -> ( - out r: double = 0.0, - out r_d: double = 0.0, + out ret: double = 0.0, + out ret_d: double = 0.0, ) = { - r_d = x_d + y_d; - r = x + y; + ret_d = x_d + y_d; + ret = x + y; return; } @@ -493,8 +493,8 @@ ad_test:/* @autodiff @print */ type = ) = { temp_2: _ = func_d(x, x_d, y, y_d); - temp_1: _ = temp_2.r; - temp_1_d: _ = temp_2.r_d; + temp_1: _ = temp_2.ret; + temp_1_d: _ = temp_2.ret_d; r_d = x * temp_1_d + temp_1 * x_d; r = x * temp_1; return; diff --git a/source/reflect.h b/source/reflect.h index 3c31443d9..6ae358f77 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -112,91 +112,94 @@ class simple_traverser; class autodiff_special_func; #line 3983 "reflect.h2" +class autodiff_declaration_stack_item; + +#line 3998 "reflect.h2" class autodiff_context; -#line 4082 "reflect.h2" +#line 4150 "reflect.h2" class autodiff_handler_base; -#line 4096 "reflect.h2" +#line 4164 "reflect.h2" class autodiff_expression_handler; -#line 4507 "reflect.h2" +#line 4598 "reflect.h2" class autodiff_stmt_handler; -#line 4890 "reflect.h2" +#line 4983 "reflect.h2" class expression_flags; -#line 4906 "reflect.h2" +#line 4999 "reflect.h2" class regex_token; -#line 4933 "reflect.h2" +#line 5026 "reflect.h2" class regex_token_check; -#line 4954 "reflect.h2" +#line 5047 "reflect.h2" class regex_token_code; -#line 4975 "reflect.h2" +#line 5068 "reflect.h2" class regex_token_empty; -#line 4993 "reflect.h2" +#line 5086 "reflect.h2" class regex_token_list; -#line 5045 "reflect.h2" +#line 5138 "reflect.h2" class parse_context_group_state; -#line 5106 "reflect.h2" +#line 5199 "reflect.h2" class parse_context_branch_reset_state; -#line 5149 "reflect.h2" +#line 5242 "reflect.h2" class parse_context; -#line 5550 "reflect.h2" +#line 5643 "reflect.h2" class generation_function_context; -#line 5568 "reflect.h2" +#line 5661 "reflect.h2" class generation_context; -#line 5767 "reflect.h2" +#line 5860 "reflect.h2" class alternative_token; -#line 5782 "reflect.h2" +#line 5875 "reflect.h2" class alternative_token_gen; -#line 5847 "reflect.h2" +#line 5940 "reflect.h2" class any_token; -#line 5864 "reflect.h2" +#line 5957 "reflect.h2" class atomic_group_token; -#line 5894 "reflect.h2" +#line 5987 "reflect.h2" class char_token; -#line 6009 "reflect.h2" +#line 6102 "reflect.h2" class class_token; -#line 6233 "reflect.h2" +#line 6326 "reflect.h2" class group_ref_token; -#line 6370 "reflect.h2" +#line 6463 "reflect.h2" class group_token; -#line 6717 "reflect.h2" +#line 6810 "reflect.h2" class lookahead_lookbehind_token; -#line 6812 "reflect.h2" +#line 6905 "reflect.h2" class range_token; -#line 6969 "reflect.h2" +#line 7062 "reflect.h2" class special_range_token; -#line 7055 "reflect.h2" +#line 7148 "reflect.h2" template class regex_generator; -#line 7312 "reflect.h2" +#line 7405 "reflect.h2" } } @@ -1664,10 +1667,25 @@ class autodiff_special_func { #line 3981 "reflect.h2" }; +class autodiff_declaration_stack_item { + public: std::string full_name; + public: meta::type_or_namespace_declaration decl; +using lookup_declaration_ret = std::vector; + + +#line 3987 "reflect.h2" + public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; + public: autodiff_declaration_stack_item(auto&& full_name_, auto&& decl_) +CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; + + +#line 3996 "reflect.h2" +}; + class autodiff_context { private: int temporary_count {0}; -#line 3995 "reflect.h2" +#line 4010 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, true, false, "_rd_ = cos(_a1_) * _ad1_;\n" @@ -1693,40 +1711,56 @@ class autodiff_context { "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n")}; -#line 4021 "reflect.h2" +#line 4036 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4025 "reflect.h2" +#line 4040 "reflect.h2" public: std::string ad_type {"double"}; + public: std::map> declaration_map {}; + public: std::vector declaration_stack {}; + + public: auto create_namespace_stack(cpp2::impl::in t) & -> void; + +#line 4062 "reflect.h2" public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4038 "reflect.h2" +#line 4073 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4046 "reflect.h2" +#line 4081 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; +using lookup_declaration_ret = std::vector; + + +#line 4090 "reflect.h2" + public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; +using lookup_function_declaration_ret = std::vector; + + +#line 4113 "reflect.h2" + public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4055 "reflect.h2" +#line 4123 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4074 "reflect.h2" +#line 4142 "reflect.h2" public: auto enter_function() & -> void; -#line 4078 "reflect.h2" +#line 4146 "reflect.h2" public: auto leave_function() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4080 "reflect.h2" +#line 4148 "reflect.h2" }; class autodiff_handler_base { @@ -1735,21 +1769,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4087 "reflect.h2" +#line 4155 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4091 "reflect.h2" +#line 4159 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4094 "reflect.h2" +#line 4162 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4100 "reflect.h2" +#line 4168 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1758,180 +1792,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4117 "reflect.h2" +#line 4185 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4136 "reflect.h2" +#line 4204 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4145 "reflect.h2" +#line 4213 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4183 "reflect.h2" +#line 4251 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4280 "reflect.h2" +#line 4371 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4313 "reflect.h2" +#line 4404 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4317 "reflect.h2" +#line 4408 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4321 "reflect.h2" +#line 4412 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4325 "reflect.h2" +#line 4416 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4329 "reflect.h2" +#line 4420 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4333 "reflect.h2" +#line 4424 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4337 "reflect.h2" +#line 4428 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4341 "reflect.h2" +#line 4432 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4345 "reflect.h2" +#line 4436 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4349 "reflect.h2" +#line 4440 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4353 "reflect.h2" +#line 4444 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4357 "reflect.h2" +#line 4448 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4381 "reflect.h2" +#line 4472 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4438 "reflect.h2" +#line 4529 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4442 "reflect.h2" +#line 4533 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4447 "reflect.h2" +#line 4538 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4474 "reflect.h2" +#line 4565 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4505 "reflect.h2" +#line 4596 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4511 "reflect.h2" +#line 4602 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4520 "reflect.h2" +#line 4611 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4525 "reflect.h2" +#line 4616 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4530 "reflect.h2" +#line 4621 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4548 "reflect.h2" +#line 4639 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4553 "reflect.h2" +#line 4644 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4558 "reflect.h2" +#line 4649 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4563 "reflect.h2" +#line 4654 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4571 "reflect.h2" +#line 4662 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4587 "reflect.h2" +#line 4678 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4634 "reflect.h2" +#line 4725 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4645 "reflect.h2" +#line 4736 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4673 "reflect.h2" +#line 4764 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4678 "reflect.h2" +#line 4769 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4682 "reflect.h2" +#line 4773 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4686 "reflect.h2" +#line 4777 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4690 "reflect.h2" +#line 4781 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4694 "reflect.h2" +#line 4785 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4698 "reflect.h2" +#line 4789 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4702 "reflect.h2" +#line 4793 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4706 "reflect.h2" +#line 4797 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4710 "reflect.h2" +#line 4801 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4714 "reflect.h2" +#line 4805 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4718 "reflect.h2" +#line 4809 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4722 "reflect.h2" +#line 4813 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4726 "reflect.h2" +#line 4817 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4731 "reflect.h2" +#line 4822 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4760 "reflect.h2" +#line 4851 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4764 "reflect.h2" +#line 4855 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4886 "reflect.h2" +#line 4979 "reflect.h2" using error_func = std::function x)>; -#line 4890 "reflect.h2" +#line 4983 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -1966,20 +2000,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4898 "reflect.h2" +#line 4991 "reflect.h2" }; -#line 4906 "reflect.h2" +#line 4999 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 4914 "reflect.h2" +#line 5007 "reflect.h2" public: explicit regex_token(); -#line 4919 "reflect.h2" +#line 5012 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -1991,103 +2025,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 4925 "reflect.h2" +#line 5018 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 4931 "reflect.h2" +#line 5024 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 4937 "reflect.h2" +#line 5030 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 4944 "reflect.h2" +#line 5037 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4948 "reflect.h2" +#line 5041 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 4949 "reflect.h2" +#line 5042 "reflect.h2" }; -#line 4952 "reflect.h2" +#line 5045 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 4958 "reflect.h2" +#line 5051 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 4965 "reflect.h2" +#line 5058 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 4969 "reflect.h2" +#line 5062 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 4970 "reflect.h2" +#line 5063 "reflect.h2" }; -#line 4973 "reflect.h2" +#line 5066 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 4979 "reflect.h2" +#line 5072 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 4983 "reflect.h2" +#line 5076 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 4987 "reflect.h2" +#line 5080 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 4988 "reflect.h2" +#line 5081 "reflect.h2" }; -#line 4991 "reflect.h2" +#line 5084 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 4997 "reflect.h2" +#line 5090 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5004 "reflect.h2" +#line 5097 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5010 "reflect.h2" +#line 5103 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5016 "reflect.h2" +#line 5109 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5024 "reflect.h2" +#line 5117 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2095,10 +2129,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5036 "reflect.h2" +#line 5129 "reflect.h2" }; -#line 5039 "reflect.h2" +#line 5132 "reflect.h2" // // Parse and generation context. // @@ -2114,33 +2148,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5059 "reflect.h2" +#line 5152 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5066 "reflect.h2" +#line 5159 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5078 "reflect.h2" +#line 5171 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5083 "reflect.h2" +#line 5176 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5087 "reflect.h2" +#line 5180 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5101 "reflect.h2" +#line 5194 "reflect.h2" }; -#line 5104 "reflect.h2" +#line 5197 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2153,25 +2187,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5122 "reflect.h2" +#line 5215 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5128 "reflect.h2" +#line 5221 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5135 "reflect.h2" +#line 5228 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5142 "reflect.h2" +#line 5235 "reflect.h2" }; -#line 5145 "reflect.h2" +#line 5238 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2187,7 +2221,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5161 "reflect.h2" +#line 5254 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2195,64 +2229,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5172 "reflect.h2" +#line 5265 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5185 "reflect.h2" +#line 5278 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5193 "reflect.h2" +#line 5286 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5197 "reflect.h2" +#line 5290 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5201 "reflect.h2" +#line 5294 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5213 "reflect.h2" +#line 5306 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5220 "reflect.h2" +#line 5313 "reflect.h2" public: auto next_alternative() & -> void; -#line 5226 "reflect.h2" +#line 5319 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5232 "reflect.h2" +#line 5325 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5236 "reflect.h2" +#line 5329 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5247 "reflect.h2" +#line 5340 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5251 "reflect.h2" +#line 5344 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5257 "reflect.h2" +#line 5350 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5261 "reflect.h2" +#line 5354 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5268 "reflect.h2" +#line 5361 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5279 "reflect.h2" +#line 5372 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2260,51 +2294,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5323 "reflect.h2" +#line 5416 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5335 "reflect.h2" +#line 5428 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5348 "reflect.h2" +#line 5441 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5371 "reflect.h2" +#line 5464 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5388 "reflect.h2" +#line 5481 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5409 "reflect.h2" +#line 5502 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5419 "reflect.h2" +#line 5512 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5423 "reflect.h2" +#line 5516 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5479 "reflect.h2" +#line 5572 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5518 "reflect.h2" +#line 5611 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5533 "reflect.h2" +#line 5626 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2316,10 +2350,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5544 "reflect.h2" +#line 5637 "reflect.h2" }; -#line 5547 "reflect.h2" +#line 5640 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2329,16 +2363,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5561 "reflect.h2" +#line 5654 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5564 "reflect.h2" +#line 5657 "reflect.h2" }; -#line 5567 "reflect.h2" +#line 5660 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2358,68 +2392,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5589 "reflect.h2" +#line 5682 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5595 "reflect.h2" +#line 5688 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5604 "reflect.h2" +#line 5697 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5615 "reflect.h2" +#line 5708 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5622 "reflect.h2" +#line 5715 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5642 "reflect.h2" +#line 5735 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5652 "reflect.h2" +#line 5745 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5675 "reflect.h2" +#line 5768 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5683 "reflect.h2" +#line 5776 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5687 "reflect.h2" +#line 5780 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5693 "reflect.h2" +#line 5786 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5699 "reflect.h2" +#line 5792 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5709 "reflect.h2" +#line 5802 "reflect.h2" public: auto finish_context() & -> void; -#line 5717 "reflect.h2" +#line 5810 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5723 "reflect.h2" +#line 5816 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5727 "reflect.h2" +#line 5820 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5731 "reflect.h2" +#line 5824 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5755 "reflect.h2" +#line 5848 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2427,7 +2461,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5761 "reflect.h2" +#line 5854 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2447,27 +2481,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5780 "reflect.h2" +#line 5873 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5786 "reflect.h2" +#line 5879 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5793 "reflect.h2" +#line 5886 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5810 "reflect.h2" +#line 5903 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5817 "reflect.h2" +#line 5910 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5830 "reflect.h2" +#line 5923 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2475,19 +2509,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5842 "reflect.h2" +#line 5935 "reflect.h2" }; -#line 5845 "reflect.h2" +#line 5938 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5851 "reflect.h2" +#line 5944 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5855 "reflect.h2" +#line 5948 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2495,7 +2529,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5860 "reflect.h2" +#line 5953 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2503,17 +2537,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5868 "reflect.h2" +#line 5961 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5879 "reflect.h2" +#line 5972 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5887 "reflect.h2" +#line 5980 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2521,7 +2555,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5890 "reflect.h2" +#line 5983 "reflect.h2" }; // Regex syntax: a @@ -2529,34 +2563,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5898 "reflect.h2" +#line 5991 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5907 "reflect.h2" +#line 6000 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 5913 "reflect.h2" +#line 6006 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 5917 "reflect.h2" +#line 6010 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5940 "reflect.h2" +#line 6033 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 5961 "reflect.h2" +#line 6054 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 5979 "reflect.h2" +#line 6072 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 5994 "reflect.h2" +#line 6087 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6000 "reflect.h2" +#line 6093 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2564,33 +2598,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6004 "reflect.h2" +#line 6097 "reflect.h2" }; -#line 6007 "reflect.h2" +#line 6100 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6013 "reflect.h2" +#line 6106 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6025 "reflect.h2" +#line 6118 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6151 "reflect.h2" +#line 6244 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6160 "reflect.h2" +#line 6253 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6165 "reflect.h2" +#line 6258 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2598,20 +2632,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6172 "reflect.h2" +#line 6265 "reflect.h2" }; -#line 6175 "reflect.h2" +#line 6268 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6216 "reflect.h2" +#line 6309 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6227 "reflect.h2" +#line 6320 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2621,20 +2655,20 @@ class class_token class group_ref_token : public regex_token { -#line 6237 "reflect.h2" +#line 6330 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6249 "reflect.h2" +#line 6342 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6350 "reflect.h2" +#line 6443 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6354 "reflect.h2" +#line 6447 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2642,10 +2676,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6357 "reflect.h2" +#line 6450 "reflect.h2" }; -#line 6360 "reflect.h2" +#line 6453 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2659,29 +2693,29 @@ class group_ref_token class group_token : public regex_token { -#line 6374 "reflect.h2" +#line 6467 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6396 "reflect.h2" +#line 6489 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6410 "reflect.h2" +#line 6503 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6569 "reflect.h2" +#line 6662 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6577 "reflect.h2" +#line 6670 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6595 "reflect.h2" +#line 6688 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6626 "reflect.h2" +#line 6719 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2690,25 +2724,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6633 "reflect.h2" +#line 6726 "reflect.h2" }; -#line 6636 "reflect.h2" +#line 6729 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6677 "reflect.h2" +#line 6770 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6697 "reflect.h2" +#line 6790 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6713 "reflect.h2" +#line 6806 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2716,20 +2750,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6721 "reflect.h2" +#line 6814 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6730 "reflect.h2" +#line 6823 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6741 "reflect.h2" +#line 6834 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6748 "reflect.h2" +#line 6841 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2737,26 +2771,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6751 "reflect.h2" +#line 6844 "reflect.h2" }; -#line 6754 "reflect.h2" +#line 6847 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6782 "reflect.h2" +#line 6875 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6810 "reflect.h2" +#line 6903 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6816 "reflect.h2" +#line 6909 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2766,22 +2800,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6896 "reflect.h2" +#line 6989 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 6908 "reflect.h2" +#line 7001 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 6921 "reflect.h2" +#line 7014 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 6940 "reflect.h2" +#line 7033 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6950 "reflect.h2" +#line 7043 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6961 "reflect.h2" +#line 7054 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2789,16 +2823,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 6964 "reflect.h2" +#line 7057 "reflect.h2" }; -#line 6967 "reflect.h2" +#line 7060 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 6973 "reflect.h2" +#line 7066 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2807,7 +2841,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7003 "reflect.h2" +#line 7096 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2816,14 +2850,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7025 "reflect.h2" +#line 7118 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7047 "reflect.h2" +#line 7140 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2844,24 +2878,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7070 "reflect.h2" +#line 7163 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7105 "reflect.h2" +#line 7198 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7119 "reflect.h2" +#line 7212 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7131 "reflect.h2" +#line 7224 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7186 "reflect.h2" +#line 7279 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2872,7 +2906,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7312 "reflect.h2" +#line 7405 "reflect.h2" } } @@ -7483,7 +7517,28 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; } -#line 3986 "reflect.h2" +#line 3984 "reflect.h2" + // namespace + type name + +#line 3987 "reflect.h2" + [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ + std::vector r {}; +#line 3988 "reflect.h2" + for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { + if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { + CPP2_UFCS(push_back)(r, cur); + + // Do not break for overloads. <3 + } + }return r; + } + + autodiff_declaration_stack_item::autodiff_declaration_stack_item(auto&& full_name_, auto&& decl_) +requires (std::is_convertible_v&> && std::is_convertible_v&>) + : full_name{ CPP2_FORWARD(full_name_) } + , decl{ CPP2_FORWARD(decl_) }{} + +#line 4001 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7496,19 +7551,37 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in /* has_return = */ /* is_member = */ -#line 4003 "reflect.h2" +#line 4018 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4010 "reflect.h2" +#line 4025 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4016 "reflect.h2" +#line 4031 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4024 "reflect.h2" +#line 4039 "reflect.h2" // Members depending on order -#line 4027 "reflect.h2" +#line 4045 "reflect.h2" + auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ + if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { + create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); + } + else {if (CPP2_UFCS(parent_is_type)(t)) { + create_namespace_stack(CPP2_UFCS(as_type)(CPP2_UFCS(get_parent)(t))); + }} + + std::string full_name {"::"}; + if (!(CPP2_UFCS(empty)(declaration_stack))) { + full_name = CPP2_UFCS(back)(declaration_stack).full_name + "::"; + } + full_name += CPP2_UFCS(name)(t); + + static_cast(CPP2_UFCS(emplace_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); + } + +#line 4062 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7520,17 +7593,17 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4038 "reflect.h2" +#line 4073 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4040 "reflect.h2" +#line 4075 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4046 "reflect.h2" +#line 4081 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ if (order == 1) { @@ -7540,11 +7613,50 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return string_util::replace_all(type, "double", ad_type); } -#line 4055 "reflect.h2" +#line 4090 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ + std::vector r {}; +#line 4091 "reflect.h2" + for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { + + std::string cur_full_name {cur.full_name + "::" + decl_name}; + auto ele {CPP2_UFCS(find)(declaration_map, cur_full_name)}; + if (ele == CPP2_UFCS(end)(declaration_map)) { + ele = CPP2_UFCS(insert_or_assign)(declaration_map, cpp2::move(cur_full_name), CPP2_UFCS(lookup_declaration)(cur, decl_name)).first; + } + + if (!(CPP2_UFCS(empty)((*cpp2::impl::assert_not_null(ele)).second))) { + // A simple assignment or emplace_back did not work. It tired to use move copy operators. + for ( auto const& cp : (*cpp2::impl::assert_not_null(cpp2::move(ele))).second ) { + CPP2_UFCS(push_back)(r, cp); + } + //r = ele*.second; + break; + // TODO: For overload resolution we may want to continue here and just add everything for all parent namespaces. + } + } + + return r; + } + +#line 4113 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ + std::vector r {}; +#line 4114 "reflect.h2" + auto r_all {lookup_declaration(decl_name)}; + + for ( auto const& cur : cpp2::move(r_all) ) { + if (CPP2_UFCS(is_function)(cur)) { + CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); + } + }return r; + } + +#line 4123 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4056 "reflect.h2" +#line 4124 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7563,36 +7675,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return { std::move(m.value()), std::move(code.value()) }; } -#line 4074 "reflect.h2" +#line 4142 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4078 "reflect.h2" +#line 4146 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4087 "reflect.h2" +#line 4155 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4089 "reflect.h2" +#line 4157 "reflect.h2" } -#line 4087 "reflect.h2" +#line 4155 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4089 "reflect.h2" +#line 4157 "reflect.h2" } -#line 4091 "reflect.h2" +#line 4159 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4106 "reflect.h2" +#line 4174 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7600,13 +7712,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4112 "reflect.h2" +#line 4180 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4117 "reflect.h2" +#line 4185 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7626,7 +7738,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in } } -#line 4136 "reflect.h2" +#line 4204 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7636,7 +7748,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return args; } -#line 4145 "reflect.h2" +#line 4213 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7675,7 +7787,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }} } -#line 4183 "reflect.h2" +#line 4251 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7683,7 +7795,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in { auto i{0}; -#line 4189 "reflect.h2" +#line 4257 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7697,7 +7809,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4201 "reflect.h2" +#line 4269 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7720,7 +7832,7 @@ auto i{0}; { auto i{0}; -#line 4222 "reflect.h2" +#line 4290 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7745,7 +7857,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4245 "reflect.h2" +#line 4313 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -7767,21 +7879,44 @@ auto i{0}; } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. - diff += "" + cpp2::to_string(cpp2::move(function_name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "("; + diff += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "("; for ( auto const& arg : cpp2::move(args) ) { diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ","; } diff += ");\n"; if (has_return) { - // TODO: Look up return value name of function. - gen_lhs_assignment("" + cpp2::to_string(ret_temp) + ".r", "" + cpp2::to_string(ret_temp) + ".r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "", true);/* switch order = */ + auto functions {CPP2_UFCS(lookup_function_declaration)((*cpp2::impl::assert_not_null(ctx)), function_name)}; + if (CPP2_UFCS(ssize)(functions) == 0) { + CPP2_UFCS(error)(postfix, "AD: Could not find function declaration for `" + cpp2::to_string(cpp2::move(function_name)) + "`.\n" + " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this function."); + } + else {if (CPP2_UFCS(ssize)(functions) != 1) { + CPP2_UFCS(error)(postfix, "AD: No handling for overload resultion is currently implemented."); + }} + + std::string ret_name {"r"}; // Default for regular return. + auto returns {CPP2_UFCS(get_returns)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(functions), 0))}; + if (!(CPP2_UFCS(empty)(returns))) { + if (CPP2_UFCS(ssize)(returns) != 1) { + CPP2_UFCS(error)(postfix, "AD: Expecting single return."); + } + + for ( auto const& cur : cpp2::move(returns) ) { + ret_name = CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur)); + } + } + + std::string ret_name_d {ret_name + (*cpp2::impl::assert_not_null(ctx)).suffix}; + + gen_lhs_assignment("" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + "", "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + "", true);/* switch order = */ } // TODO: Add function to list of functions/objects for differentiation. } -#line 4280 "reflect.h2" +#line 4371 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7806,75 +7941,75 @@ auto i{0}; { auto i{1}; -#line 4303 "reflect.h2" +#line 4394 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4308 "reflect.h2" +#line 4399 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4313 "reflect.h2" +#line 4404 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4317 "reflect.h2" +#line 4408 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4321 "reflect.h2" +#line 4412 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4325 "reflect.h2" +#line 4416 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4329 "reflect.h2" +#line 4420 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4333 "reflect.h2" +#line 4424 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4337 "reflect.h2" +#line 4428 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4341 "reflect.h2" +#line 4432 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4345 "reflect.h2" +#line 4436 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4349 "reflect.h2" +#line 4440 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4353 "reflect.h2" +#line 4444 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4357 "reflect.h2" +#line 4448 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7899,7 +8034,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4381 "reflect.h2" +#line 4472 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7938,7 +8073,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4420 "reflect.h2" +#line 4511 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -7957,18 +8092,18 @@ auto i{1}; } } -#line 4438 "reflect.h2" +#line 4529 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4442 "reflect.h2" +#line 4533 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4447 "reflect.h2" +#line 4538 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7977,7 +8112,7 @@ auto i{1}; { auto i{0}; -#line 4454 "reflect.h2" +#line 4545 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7991,7 +8126,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4466 "reflect.h2" +#line 4557 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8000,7 +8135,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4474 "reflect.h2" +#line 4565 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8033,26 +8168,26 @@ auto i{0}; }}}} } -#line 4515 "reflect.h2" +#line 4606 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4518 "reflect.h2" +#line 4609 "reflect.h2" } -#line 4520 "reflect.h2" +#line 4611 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4525 "reflect.h2" +#line 4616 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4530 "reflect.h2" +#line 4621 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8070,22 +8205,22 @@ auto i{0}; } } -#line 4548 "reflect.h2" +#line 4639 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4553 "reflect.h2" +#line 4644 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4558 "reflect.h2" +#line 4649 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4563 "reflect.h2" +#line 4654 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8093,7 +8228,7 @@ auto i{0}; diff += "}\n"; } -#line 4571 "reflect.h2" +#line 4662 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8109,7 +8244,7 @@ auto i{0}; } } -#line 4587 "reflect.h2" +#line 4678 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8156,7 +8291,7 @@ auto i{0}; }} } -#line 4634 "reflect.h2" +#line 4725 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8168,7 +8303,7 @@ auto i{0}; } } -#line 4645 "reflect.h2" +#line 4736 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8197,79 +8332,79 @@ auto i{0}; } } -#line 4673 "reflect.h2" +#line 4764 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4678 "reflect.h2" +#line 4769 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4682 "reflect.h2" +#line 4773 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4686 "reflect.h2" +#line 4777 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4690 "reflect.h2" +#line 4781 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4694 "reflect.h2" +#line 4785 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4698 "reflect.h2" +#line 4789 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4702 "reflect.h2" +#line 4793 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4706 "reflect.h2" +#line 4797 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4710 "reflect.h2" +#line 4801 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4714 "reflect.h2" +#line 4805 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4718 "reflect.h2" +#line 4809 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4722 "reflect.h2" +#line 4813 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4726 "reflect.h2" +#line 4817 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4731 "reflect.h2" +#line 4822 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8278,7 +8413,7 @@ auto i{0}; { auto i{0}; -#line 4738 "reflect.h2" +#line 4829 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8292,7 +8427,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4750 "reflect.h2" +#line 4841 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8303,13 +8438,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4760 "reflect.h2" +#line 4851 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4766 "reflect.h2" +#line 4857 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8345,6 +8480,8 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = suffix; CPP2_UFCS(set_order)(ad_ctx, order); + CPP2_UFCS(create_namespace_stack)(ad_ctx, t); + for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_function)(m)) @@ -8393,10 +8530,10 @@ auto autodiff(meta::type_declaration& t) -> void return ; } -#line 4850 "reflect.h2" +#line 4943 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4853 "reflect.h2" +#line 4946 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) { ad_impl.pre_traverse(stmt); @@ -8506,7 +8643,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4872 "reflect.h2" +#line 4965 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8522,11 +8659,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4888 "reflect.h2" +#line 4981 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4892 "reflect.h2" +#line 4985 "reflect.h2" // mod: i // mod: m // mod: s @@ -8534,116 +8671,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4901 "reflect.h2" +#line 4994 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 4910 "reflect.h2" +#line 5003 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 4912 "reflect.h2" +#line 5005 "reflect.h2" } -#line 4914 "reflect.h2" +#line 5007 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 4916 "reflect.h2" +#line 5009 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 4922 "reflect.h2" +#line 5015 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 4923 "reflect.h2" +#line 5016 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 4924 "reflect.h2" +#line 5017 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 4939 "reflect.h2" +#line 5032 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 4942 "reflect.h2" +#line 5035 "reflect.h2" } -#line 4944 "reflect.h2" +#line 5037 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 4948 "reflect.h2" +#line 5041 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 4960 "reflect.h2" +#line 5053 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 4963 "reflect.h2" +#line 5056 "reflect.h2" } -#line 4965 "reflect.h2" +#line 5058 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 4969 "reflect.h2" +#line 5062 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 4979 "reflect.h2" +#line 5072 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 4981 "reflect.h2" +#line 5074 "reflect.h2" } -#line 4983 "reflect.h2" +#line 5076 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 4987 "reflect.h2" +#line 5080 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 4999 "reflect.h2" +#line 5092 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5002 "reflect.h2" +#line 5095 "reflect.h2" } -#line 5004 "reflect.h2" +#line 5097 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5010 "reflect.h2" +#line 5103 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5016 "reflect.h2" +#line 5109 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8652,7 +8789,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5024 "reflect.h2" +#line 5117 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8668,7 +8805,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5052 "reflect.h2" +#line 5145 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8676,14 +8813,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5060 "reflect.h2" +#line 5153 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5067 "reflect.h2" +#line 5160 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8695,15 +8832,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5079 "reflect.h2" +#line 5172 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5084 "reflect.h2" +#line 5177 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5088 "reflect.h2" +#line 5181 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8724,7 +8861,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5114 "reflect.h2" +#line 5207 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8733,20 +8870,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5123 "reflect.h2" +#line 5216 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5129 "reflect.h2" +#line 5222 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5136 "reflect.h2" +#line 5229 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8761,16 +8898,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5166 "reflect.h2" +#line 5259 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5170 "reflect.h2" +#line 5263 "reflect.h2" } -#line 5176 "reflect.h2" +#line 5269 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8780,7 +8917,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5186 "reflect.h2" +#line 5279 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8788,17 +8925,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5193 "reflect.h2" +#line 5286 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5197 "reflect.h2" +#line 5290 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5204 "reflect.h2" +#line 5297 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8808,7 +8945,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5213 "reflect.h2" +#line 5306 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8816,24 +8953,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5220 "reflect.h2" +#line 5313 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5228 "reflect.h2" +#line 5321 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5232 "reflect.h2" +#line 5325 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5236 "reflect.h2" +#line 5329 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8845,22 +8982,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5247 "reflect.h2" +#line 5340 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5253 "reflect.h2" +#line 5346 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5257 "reflect.h2" +#line 5350 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5261 "reflect.h2" +#line 5354 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -8868,7 +9005,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5268 "reflect.h2" +#line 5361 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -8880,10 +9017,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5281 "reflect.h2" +#line 5374 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5284 "reflect.h2" +#line 5377 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -8923,7 +9060,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5324 "reflect.h2" +#line 5417 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -8935,14 +9072,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5335 "reflect.h2" +#line 5428 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5336 "reflect.h2" +#line 5429 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5337 "reflect.h2" +#line 5430 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5339 "reflect.h2" +#line 5432 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -8952,10 +9089,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5348 "reflect.h2" +#line 5441 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5350 "reflect.h2" +#line 5443 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -8977,14 +9114,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5371 "reflect.h2" +#line 5464 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5372 "reflect.h2" +#line 5465 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5373 "reflect.h2" +#line 5466 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5375 "reflect.h2" +#line 5468 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -8998,7 +9135,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5388 "reflect.h2" +#line 5481 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9020,7 +9157,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5409 "reflect.h2" +#line 5502 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9031,12 +9168,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5419 "reflect.h2" +#line 5512 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5420 "reflect.h2" +#line 5513 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5425 "reflect.h2" +#line 5518 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9091,7 +9228,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5479 "reflect.h2" +#line 5572 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9131,7 +9268,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5518 "reflect.h2" +#line 5611 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9147,21 +9284,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5535 "reflect.h2" +#line 5628 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5536 "reflect.h2" +#line 5629 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5537 "reflect.h2" +#line 5630 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5539 "reflect.h2" +#line 5632 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5554 "reflect.h2" +#line 5647 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9169,7 +9306,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5561 "reflect.h2" +#line 5654 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9179,22 +9316,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5579 "reflect.h2" +#line 5672 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5584 "reflect.h2" +#line 5677 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5590 "reflect.h2" +#line 5683 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5596 "reflect.h2" +#line 5689 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9203,7 +9340,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5604 "reflect.h2" +#line 5697 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9215,7 +9352,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5615 "reflect.h2" +#line 5708 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9223,7 +9360,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5622 "reflect.h2" +#line 5715 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9244,7 +9381,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5643 "reflect.h2" +#line 5736 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9254,7 +9391,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5653 "reflect.h2" +#line 5746 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9277,33 +9414,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5677 "reflect.h2" +#line 5770 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5683 "reflect.h2" +#line 5776 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5687 "reflect.h2" +#line 5780 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5693 "reflect.h2" +#line 5786 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5701 "reflect.h2" +#line 5794 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9312,7 +9449,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5709 "reflect.h2" +#line 5802 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9321,22 +9458,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5719 "reflect.h2" +#line 5812 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5723 "reflect.h2" +#line 5816 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5727 "reflect.h2" +#line 5820 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5731 "reflect.h2" +#line 5824 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9360,18 +9497,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5756 "reflect.h2" +#line 5849 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5771 "reflect.h2" +#line 5864 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5773 "reflect.h2" +#line 5866 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9382,15 +9519,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5788 "reflect.h2" +#line 5881 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5791 "reflect.h2" +#line 5884 "reflect.h2" } -#line 5793 "reflect.h2" +#line 5886 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9408,7 +9545,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5810 "reflect.h2" +#line 5903 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9416,7 +9553,7 @@ generation_function_context::generation_function_context(){} } } -#line 5817 "reflect.h2" +#line 5910 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9430,7 +9567,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5830 "reflect.h2" +#line 5923 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9446,14 +9583,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5851 "reflect.h2" +#line 5944 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5853 "reflect.h2" +#line 5946 "reflect.h2" } -#line 5855 "reflect.h2" +#line 5948 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9462,11 +9599,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5870 "reflect.h2" +#line 5963 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5872 "reflect.h2" +#line 5965 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9474,7 +9611,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5879 "reflect.h2" +#line 5972 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9483,37 +9620,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5887 "reflect.h2" +#line 5980 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5901 "reflect.h2" +#line 5994 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5905 "reflect.h2" +#line 5998 "reflect.h2" } -#line 5907 "reflect.h2" +#line 6000 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5911 "reflect.h2" +#line 6004 "reflect.h2" } -#line 5913 "reflect.h2" +#line 6006 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 5917 "reflect.h2" +#line 6010 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9522,14 +9659,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 5923 "reflect.h2" +#line 6016 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 5928 "reflect.h2" +#line 6021 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9542,7 +9679,7 @@ size_t i{0}; } } -#line 5940 "reflect.h2" +#line 6033 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9564,7 +9701,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5961 "reflect.h2" +#line 6054 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9583,7 +9720,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 5979 "reflect.h2" +#line 6072 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9599,14 +9736,14 @@ size_t i{0}; return cpp2::move(str); } -#line 5994 "reflect.h2" +#line 6087 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6000 "reflect.h2" +#line 6093 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9614,19 +9751,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6017 "reflect.h2" +#line 6110 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6018 "reflect.h2" +#line 6111 "reflect.h2" { -#line 6023 "reflect.h2" +#line 6116 "reflect.h2" } -#line 6026 "reflect.h2" +#line 6119 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9752,7 +9889,7 @@ size_t i{0}; ); } -#line 6151 "reflect.h2" +#line 6244 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9762,13 +9899,13 @@ size_t i{0}; ); } -#line 6160 "reflect.h2" +#line 6253 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6165 "reflect.h2" +#line 6258 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9779,12 +9916,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6177 "reflect.h2" +#line 6270 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6182 "reflect.h2" +#line 6275 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9818,7 +9955,7 @@ size_t i{0}; } -#line 6218 "reflect.h2" +#line 6311 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9827,19 +9964,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6241 "reflect.h2" +#line 6334 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6242 "reflect.h2" +#line 6335 "reflect.h2" { -#line 6247 "reflect.h2" +#line 6340 "reflect.h2" } -#line 6249 "reflect.h2" +#line 6342 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -9941,19 +10078,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6350 "reflect.h2" +#line 6443 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6354 "reflect.h2" +#line 6447 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6378 "reflect.h2" +#line 6471 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9972,7 +10109,7 @@ size_t i{0}; return r; } -#line 6396 "reflect.h2" +#line 6489 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -9987,7 +10124,7 @@ size_t i{0}; return r; } -#line 6410 "reflect.h2" +#line 6503 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10147,7 +10284,7 @@ size_t i{0}; } } -#line 6569 "reflect.h2" +#line 6662 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10156,7 +10293,7 @@ size_t i{0}; return r; } -#line 6577 "reflect.h2" +#line 6670 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10175,7 +10312,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6595 "reflect.h2" +#line 6688 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10207,7 +10344,7 @@ size_t i{0}; } } -#line 6626 "reflect.h2" +#line 6719 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10218,7 +10355,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6638 "reflect.h2" +#line 6731 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10257,7 +10394,7 @@ size_t i{0}; return r; } -#line 6679 "reflect.h2" +#line 6772 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10275,7 +10412,7 @@ size_t i{0}; }} } -#line 6699 "reflect.h2" +#line 6792 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10289,16 +10426,16 @@ size_t i{0}; } } -#line 6725 "reflect.h2" +#line 6818 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6728 "reflect.h2" +#line 6821 "reflect.h2" } -#line 6730 "reflect.h2" +#line 6823 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10310,7 +10447,7 @@ size_t i{0}; } } -#line 6741 "reflect.h2" +#line 6834 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10318,14 +10455,14 @@ size_t i{0}; return r; } -#line 6748 "reflect.h2" +#line 6841 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6756 "reflect.h2" +#line 6849 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10351,7 +10488,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6784 "reflect.h2" +#line 6877 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10377,11 +10514,11 @@ size_t i{0}; return r; } -#line 6821 "reflect.h2" +#line 6914 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6823 "reflect.h2" +#line 6916 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10455,7 +10592,7 @@ size_t i{0}; return nullptr; } -#line 6896 "reflect.h2" +#line 6989 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10468,7 +10605,7 @@ size_t i{0}; }} } -#line 6908 "reflect.h2" +#line 7001 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10482,7 +10619,7 @@ size_t i{0}; }} } -#line 6921 "reflect.h2" +#line 7014 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10502,7 +10639,7 @@ size_t i{0}; return r; } -#line 6940 "reflect.h2" +#line 7033 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10513,7 +10650,7 @@ size_t i{0}; return r; } -#line 6950 "reflect.h2" +#line 7043 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10525,14 +10662,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6961 "reflect.h2" +#line 7054 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 6973 "reflect.h2" +#line 7066 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10556,7 +10693,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 6997 "reflect.h2" +#line 7090 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10566,7 +10703,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7009 "reflect.h2" +#line 7102 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10582,7 +10719,7 @@ size_t i{0}; } } -#line 7029 "reflect.h2" +#line 7122 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10600,15 +10737,15 @@ size_t i{0}; }} } -#line 7065 "reflect.h2" +#line 7158 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7068 "reflect.h2" +#line 7161 "reflect.h2" } -#line 7070 "reflect.h2" +#line 7163 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10644,7 +10781,7 @@ size_t i{0}; return source; } -#line 7105 "reflect.h2" +#line 7198 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10660,7 +10797,7 @@ size_t i{0}; } } -#line 7121 "reflect.h2" +#line 7214 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10669,7 +10806,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10724,7 +10861,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7190 "reflect.h2" +#line 7283 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10846,7 +10983,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7312 "reflect.h2" +#line 7405 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index d5ee00306..3e4f6675f 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3980,6 +3980,21 @@ autodiff_special_func: type = { } } +autodiff_declaration_stack_item: @struct type = { + full_name: std::string; // namespace + type name + decl: meta::type_or_namespace_declaration; + + lookup_declaration: (this, decl_name: std::string) -> (r: std::vector = ()) = { + for decl.get_members() do (cur) { + if cur.has_name() && decl_name == cur.name() { + r.push_back(cur); + + // Do not break for overloads. <3 + } + } + } +} + autodiff_context: type = { private temporary_count : int = 0; @@ -4024,6 +4039,26 @@ autodiff_context: type = { // Members depending on order public ad_type: std::string = "double"; + public declaration_map : std::map> = (); + public declaration_stack: std::vector = (); + + create_namespace_stack: (inout this, t: meta::type_or_namespace_declaration) = { + if t.parent_is_nonglobal_namespace() { + create_namespace_stack(t.get_parent().as_nonglobal_namespace()); + } + else if t.parent_is_type() { + create_namespace_stack(t.get_parent().as_type()); + } + + full_name: std::string = "::"; + if !declaration_stack.empty() { + full_name = declaration_stack.back().full_name + "::"; + } + full_name += t.name(); + + _ = declaration_stack.emplace_back(autodiff_declaration_stack_item(full_name, t)); + } + set_order : (inout this, new_order: int) = { order = new_order; @@ -4052,6 +4087,39 @@ autodiff_context: type = { return string_util::replace_all(type, "double", ad_type); } + lookup_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { + for std::ranges::views::reverse(declaration_stack) do (cur) { + + cur_full_name : std::string = cur.full_name + "::" + decl_name; + ele := declaration_map.find(cur_full_name); + if ele == declaration_map.end() { + ele = declaration_map.insert_or_assign(cur_full_name, cur.lookup_declaration(decl_name)).first; + } + + if !ele*.second.empty() { + // A simple assignment or emplace_back did not work. It tired to use move copy operators. + for ele*.second do (cp) { + r.push_back(cp); + } + //r = ele*.second; + break; + // TODO: For overload resolution we may want to continue here and just add everything for all parent namespaces. + } + } + + return; + } + + lookup_function_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { + r_all := lookup_declaration(decl_name); + + for r_all do (cur) { + if cur.is_function() { + r.push_back(cur.as_function()); + } + } + } + lookup_special_function_handling: (this, func_name: std::string, n_args: int, has_return: bool, is_member: bool) -> (m: bool, code: std::string) = { lookup : autodiff_special_func = (func_name, n_args, has_return, is_member); @@ -4270,8 +4338,31 @@ autodiff_expression_handler: type = { diff += ");\n"; if has_return { - // TODO: Look up return value name of function. - gen_lhs_assignment("(ret_temp)$.r", "(ret_temp)$.r(ctx*.suffix)$", /* switch order = */ true); + functions := ctx*.lookup_function_declaration(function_name); + if functions.ssize() == 0 { + postfix.error("AD: Could not find function declaration for `(function_name)$`.\n" + " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this function."); + } + else if functions.ssize() != 1 { + postfix.error("AD: No handling for overload resultion is currently implemented."); + } + + ret_name : std::string = "r"; // Default for regular return. + returns := functions[0].get_returns(); + if !returns.empty() { + if returns.ssize() != 1 { + postfix.error("AD: Expecting single return."); + } + + for returns do (cur) { + ret_name = cur.get_declaration().name(); + } + } + + ret_name_d : std::string = ret_name + ctx*.suffix; + + gen_lhs_assignment("(ret_temp)$.(ret_name)$", "(ret_temp)$.(ret_name_d)$", /* switch order = */ true); } // TODO: Add function to list of functions/objects for differentiation. @@ -4798,6 +4889,8 @@ autodiff: (inout t: meta::type_declaration) = ad_ctx.suffix = suffix; ad_ctx.set_order(order); + ad_ctx.create_namespace_stack(t); + for t.get_members() do (m) if m.is_function() From d9ac9e1c4c588764053f644022d91e29f2d51227 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 15 Aug 2025 11:45:49 +0200 Subject: [PATCH 28/54] Basic changes for adding new things for the differentiation. --- source/reflect.h | 2926 +++++++++++++++++++++++---------------------- source/reflect.h2 | 90 +- 2 files changed, 1606 insertions(+), 1410 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 6ae358f77..33da6e13d 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -24,182 +24,182 @@ class compiler_services; #line 189 "reflect.h2" template class reflection_base; -#line 222 "reflect.h2" +#line 225 "reflect.h2" class declaration; -#line 307 "reflect.h2" +#line 310 "reflect.h2" class function_declaration; -#line 412 "reflect.h2" +#line 415 "reflect.h2" class object_declaration; -#line 448 "reflect.h2" +#line 451 "reflect.h2" class type_or_namespace_declaration; -#line 558 "reflect.h2" +#line 561 "reflect.h2" class type_declaration; -#line 601 "reflect.h2" +#line 604 "reflect.h2" class namespace_declaration; -#line 620 "reflect.h2" +#line 623 "reflect.h2" class alias_declaration; -#line 639 "reflect.h2" +#line 642 "reflect.h2" class parameter_declaration; -#line 685 "reflect.h2" +#line 688 "reflect.h2" template class binary_expression; -#line 812 "reflect.h2" +#line 815 "reflect.h2" class expression_list; -#line 845 "reflect.h2" +#line 848 "reflect.h2" class prefix_expression; -#line 887 "reflect.h2" +#line 890 "reflect.h2" class postfix_expression; -#line 958 "reflect.h2" +#line 961 "reflect.h2" class template_arg; -#line 984 "reflect.h2" +#line 987 "reflect.h2" class unqualified_id; -#line 1016 "reflect.h2" +#line 1019 "reflect.h2" class qualified_id; -#line 1060 "reflect.h2" +#line 1063 "reflect.h2" class type_id; -#line 1103 "reflect.h2" +#line 1106 "reflect.h2" class primary_expression; -#line 1142 "reflect.h2" +#line 1145 "reflect.h2" class id_expression; -#line 1178 "reflect.h2" +#line 1181 "reflect.h2" class expression; -#line 1229 "reflect.h2" +#line 1232 "reflect.h2" class is_as_expression; -#line 1290 "reflect.h2" +#line 1293 "reflect.h2" class statement; -#line 1332 "reflect.h2" +#line 1335 "reflect.h2" class expression_statement; -#line 1354 "reflect.h2" +#line 1357 "reflect.h2" class compound_statement; -#line 1393 "reflect.h2" +#line 1396 "reflect.h2" class selection_statement; -#line 1419 "reflect.h2" +#line 1422 "reflect.h2" class return_statement; -#line 1441 "reflect.h2" +#line 1444 "reflect.h2" class iteration_statement; -#line 1938 "reflect.h2" +#line 1941 "reflect.h2" class value_member_info; -#line 2472 "reflect.h2" +#line 2475 "reflect.h2" class simple_traverser; -#line 3954 "reflect.h2" +#line 3957 "reflect.h2" class autodiff_special_func; -#line 3983 "reflect.h2" +#line 3986 "reflect.h2" class autodiff_declaration_stack_item; -#line 3998 "reflect.h2" +#line 4009 "reflect.h2" class autodiff_context; -#line 4150 "reflect.h2" +#line 4222 "reflect.h2" class autodiff_handler_base; -#line 4164 "reflect.h2" +#line 4236 "reflect.h2" class autodiff_expression_handler; -#line 4598 "reflect.h2" +#line 4672 "reflect.h2" class autodiff_stmt_handler; -#line 4983 "reflect.h2" +#line 5063 "reflect.h2" class expression_flags; -#line 4999 "reflect.h2" +#line 5079 "reflect.h2" class regex_token; -#line 5026 "reflect.h2" +#line 5106 "reflect.h2" class regex_token_check; -#line 5047 "reflect.h2" +#line 5127 "reflect.h2" class regex_token_code; -#line 5068 "reflect.h2" +#line 5148 "reflect.h2" class regex_token_empty; -#line 5086 "reflect.h2" +#line 5166 "reflect.h2" class regex_token_list; -#line 5138 "reflect.h2" +#line 5218 "reflect.h2" class parse_context_group_state; -#line 5199 "reflect.h2" +#line 5279 "reflect.h2" class parse_context_branch_reset_state; -#line 5242 "reflect.h2" +#line 5322 "reflect.h2" class parse_context; -#line 5643 "reflect.h2" +#line 5723 "reflect.h2" class generation_function_context; -#line 5661 "reflect.h2" +#line 5741 "reflect.h2" class generation_context; -#line 5860 "reflect.h2" +#line 5940 "reflect.h2" class alternative_token; -#line 5875 "reflect.h2" +#line 5955 "reflect.h2" class alternative_token_gen; -#line 5940 "reflect.h2" +#line 6020 "reflect.h2" class any_token; -#line 5957 "reflect.h2" +#line 6037 "reflect.h2" class atomic_group_token; -#line 5987 "reflect.h2" +#line 6067 "reflect.h2" class char_token; -#line 6102 "reflect.h2" +#line 6182 "reflect.h2" class class_token; -#line 6326 "reflect.h2" +#line 6406 "reflect.h2" class group_ref_token; -#line 6463 "reflect.h2" +#line 6543 "reflect.h2" class group_token; -#line 6810 "reflect.h2" +#line 6890 "reflect.h2" class lookahead_lookbehind_token; -#line 6905 "reflect.h2" +#line 6985 "reflect.h2" class range_token; -#line 7062 "reflect.h2" +#line 7142 "reflect.h2" class special_range_token; -#line 7148 "reflect.h2" +#line 7228 "reflect.h2" template class regex_generator; -#line 7405 "reflect.h2" +#line 7485 "reflect.h2" } } @@ -316,25 +316,28 @@ template class reflection_base public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; + + public: [[nodiscard]] auto is_same(cpp2::impl::in o) const& -> bool; + public: template [[nodiscard]] auto is_same(reflection_base const& o) const& -> bool; public: virtual ~reflection_base() noexcept; public: reflection_base(reflection_base const& that); public: reflection_base(reflection_base&& that) noexcept; -#line 209 "reflect.h2" +#line 212 "reflect.h2" }; -#line 222 "reflect.h2" +#line 225 "reflect.h2" class declaration : public reflection_base { -#line 226 "reflect.h2" +#line 229 "reflect.h2" public: declaration( declaration_node* n_, cpp2::impl::in s ); -#line 235 "reflect.h2" +#line 238 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -353,7 +356,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 256 "reflect.h2" +#line 259 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto get_initializer() const& -> statement; @@ -399,21 +402,21 @@ public: declaration(declaration const& that); public: declaration(declaration&& that) noexcept; -#line 301 "reflect.h2" +#line 304 "reflect.h2" }; -#line 307 "reflect.h2" +#line 310 "reflect.h2" class function_declaration : public declaration { -#line 311 "reflect.h2" +#line 314 "reflect.h2" public: function_declaration( declaration_node* n_, cpp2::impl::in s ); -#line 321 "reflect.h2" +#line 324 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::impl::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::impl::in s) const& -> bool; public: [[nodiscard]] auto has_return_named(cpp2::impl::in s) const& -> bool; @@ -463,10 +466,10 @@ class function_declaration public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 378 "reflect.h2" +#line 381 "reflect.h2" public: [[nodiscard]] auto get_returns() const& -> std::vector; -#line 390 "reflect.h2" +#line 393 "reflect.h2" public: [[nodiscard]] auto default_to_virtual() & -> decltype(auto); public: [[nodiscard]] auto make_virtual() & -> bool; @@ -476,88 +479,88 @@ class function_declaration public: function_declaration(function_declaration&& that) noexcept; -#line 406 "reflect.h2" +#line 409 "reflect.h2" }; -#line 412 "reflect.h2" +#line 415 "reflect.h2" class object_declaration : public declaration { -#line 416 "reflect.h2" +#line 419 "reflect.h2" public: object_declaration( declaration_node* n_, cpp2::impl::in s ); -#line 426 "reflect.h2" +#line 429 "reflect.h2" public: [[nodiscard]] auto is_const() const& -> bool; public: [[nodiscard]] auto has_wildcard_type() const& -> bool; public: [[nodiscard]] auto type() const& -> std::string; -#line 436 "reflect.h2" +#line 439 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); public: object_declaration(object_declaration&& that) noexcept; -#line 442 "reflect.h2" +#line 445 "reflect.h2" }; -#line 448 "reflect.h2" +#line 451 "reflect.h2" class type_or_namespace_declaration : public declaration { -#line 452 "reflect.h2" +#line 455 "reflect.h2" public: type_or_namespace_declaration( declaration_node* n_, cpp2::impl::in s ); -#line 462 "reflect.h2" +#line 465 "reflect.h2" public: auto reserve_names(cpp2::impl::in name, auto&& ...etc) const& -> void; -#line 476 "reflect.h2" +#line 479 "reflect.h2" public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 487 "reflect.h2" +#line 490 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 502 "reflect.h2" +#line 505 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 512 "reflect.h2" +#line 515 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 522 "reflect.h2" +#line 525 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 532 "reflect.h2" +#line 535 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; -#line 542 "reflect.h2" +#line 545 "reflect.h2" public: auto add_member(cpp2::impl::in source) & -> void; public: type_or_namespace_declaration(type_or_namespace_declaration const& that); public: type_or_namespace_declaration(type_or_namespace_declaration&& that) noexcept; -#line 555 "reflect.h2" +#line 558 "reflect.h2" }; -#line 558 "reflect.h2" +#line 561 "reflect.h2" class type_declaration : public type_or_namespace_declaration { -#line 562 "reflect.h2" +#line 565 "reflect.h2" public: type_declaration( declaration_node* n_, cpp2::impl::in s ); -#line 573 "reflect.h2" +#line 576 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; @@ -565,26 +568,26 @@ struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_ -#line 577 "reflect.h2" +#line 580 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 593 "reflect.h2" +#line 596 "reflect.h2" public: [[nodiscard]] auto disable_member_function_generation() & -> decltype(auto); -#line 596 "reflect.h2" +#line 599 "reflect.h2" public: [[nodiscard]] auto remove_marked_members() & -> decltype(auto); public: [[nodiscard]] auto remove_all_members() & -> decltype(auto); public: type_declaration(type_declaration const& that); public: type_declaration(type_declaration&& that) noexcept; -#line 598 "reflect.h2" +#line 601 "reflect.h2" }; -#line 601 "reflect.h2" +#line 604 "reflect.h2" class namespace_declaration : public type_or_namespace_declaration { -#line 605 "reflect.h2" +#line 608 "reflect.h2" public: namespace_declaration( declaration_node* n_, @@ -594,14 +597,14 @@ class namespace_declaration public: namespace_declaration(namespace_declaration&& that) noexcept; -#line 614 "reflect.h2" +#line 617 "reflect.h2" }; -#line 620 "reflect.h2" +#line 623 "reflect.h2" class alias_declaration : public declaration { -#line 624 "reflect.h2" +#line 627 "reflect.h2" public: alias_declaration( declaration_node* n_, @@ -611,21 +614,21 @@ class alias_declaration public: alias_declaration(alias_declaration&& that) noexcept; -#line 633 "reflect.h2" +#line 636 "reflect.h2" }; -#line 639 "reflect.h2" +#line 642 "reflect.h2" class parameter_declaration : public reflection_base { -#line 643 "reflect.h2" +#line 646 "reflect.h2" public: parameter_declaration( parameter_declaration_node* n_, cpp2::impl::in s ); -#line 652 "reflect.h2" +#line 655 "reflect.h2" public: [[nodiscard]] auto get_declaration() const& -> object_declaration; public: [[nodiscard]] auto get_passing_style() const& -> passing_style; @@ -636,10 +639,10 @@ class parameter_declaration public: parameter_declaration(parameter_declaration const& that); public: parameter_declaration(parameter_declaration&& that) noexcept; -#line 659 "reflect.h2" +#line 662 "reflect.h2" }; -#line 672 "reflect.h2" +#line 675 "reflect.h2" using multiplicative_expression = binary_expression<"multiplicative",is_as_expression_node>; using additive_expression = binary_expression<"additive",multiplicative_expression_node>; using shift_expression = binary_expression<"shift",additive_expression_node>; @@ -656,14 +659,14 @@ using assignment_expression = binary_expression<"assignment",logical_or_expressi template class binary_expression : public reflection_base> { -#line 689 "reflect.h2" +#line 692 "reflect.h2" public: binary_expression( binary_expression_node* n_, cpp2::impl::in s ); -#line 698 "reflect.h2" +#line 701 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto lhs_is_id_expression() const& -> bool; public: [[nodiscard]] auto is_standalone_expression() const& -> bool; @@ -688,16 +691,16 @@ public: auto operator=(term_t const& that) -> term_t& ; public: term_t(term_t&& that) noexcept; public: auto operator=(term_t&& that) noexcept -> term_t& ; -#line 716 "reflect.h2" +#line 719 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 793 "reflect.h2" +#line 796 "reflect.h2" public: [[nodiscard]] auto as_expression_list() const& -> expression_list; public: [[nodiscard]] auto as_literal() const& -> std::string; -#line 797 "reflect.h2" +#line 800 "reflect.h2" public: [[nodiscard]] auto get_if_only_a_postfix_expression() const& -> postfix_expression; public: [[nodiscard]] auto get_lhs_postfix_expression() const& -> postfix_expression; @@ -710,49 +713,49 @@ public: auto operator=(term_t&& that) noexcept -> term_t& ; public: binary_expression(binary_expression const& that); public: binary_expression(binary_expression&& that) noexcept; -#line 806 "reflect.h2" +#line 809 "reflect.h2" }; -#line 812 "reflect.h2" +#line 815 "reflect.h2" class expression_list : public reflection_base { -#line 816 "reflect.h2" +#line 819 "reflect.h2" public: expression_list( expression_list_node* n_, cpp2::impl::in s ); -#line 825 "reflect.h2" +#line 828 "reflect.h2" public: [[nodiscard]] auto is_empty() const& -> bool; public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto get_expressions() const& -> std::vector; -#line 838 "reflect.h2" +#line 841 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: expression_list(expression_list const& that); public: expression_list(expression_list&& that) noexcept; -#line 839 "reflect.h2" +#line 842 "reflect.h2" }; -#line 845 "reflect.h2" +#line 848 "reflect.h2" class prefix_expression : public reflection_base { -#line 849 "reflect.h2" +#line 852 "reflect.h2" public: prefix_expression( prefix_expression_node* n_, cpp2::impl::in s ); -#line 858 "reflect.h2" +#line 861 "reflect.h2" public: [[nodiscard]] auto get_ops() const& -> std::vector; -#line 866 "reflect.h2" +#line 869 "reflect.h2" public: [[nodiscard]] auto get_postfix_expression() const& -> postfix_expression; public: [[nodiscard]] auto is_fold_expression() const& -> bool; @@ -772,21 +775,21 @@ class prefix_expression public: prefix_expression(prefix_expression const& that); public: prefix_expression(prefix_expression&& that) noexcept; -#line 881 "reflect.h2" +#line 884 "reflect.h2" }; -#line 887 "reflect.h2" +#line 890 "reflect.h2" class postfix_expression : public reflection_base { -#line 891 "reflect.h2" +#line 894 "reflect.h2" public: postfix_expression( postfix_expression_node* n_, cpp2::impl::in s ); -#line 900 "reflect.h2" +#line 903 "reflect.h2" public: [[nodiscard]] auto get_primary_expression() const& -> primary_expression; public: class term_t { @@ -797,7 +800,7 @@ class postfix_expression public: [[nodiscard]] auto get_op() const& -> std::string_view; -#line 916 "reflect.h2" +#line 919 "reflect.h2" public: [[nodiscard]] auto is_id_expression() const& -> bool; public: [[nodiscard]] auto is_expression_list() const& -> bool; public: [[nodiscard]] auto is_expression() const& -> bool; @@ -808,12 +811,12 @@ class postfix_expression public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 923 "reflect.h2" +#line 926 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 931 "reflect.h2" +#line 934 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -827,7 +830,7 @@ public: term_t(term_t&& that) noexcept; public: [[nodiscard]] auto get_first_token_ignoring_this() const& -> std::string_view; -#line 948 "reflect.h2" +#line 951 "reflect.h2" public: [[nodiscard]] auto starts_with_function_call_with_num_parameters(cpp2::impl::in num) const& -> bool; public: [[nodiscard]] auto is_result_a_temporary_variable() const& -> bool; @@ -835,21 +838,21 @@ public: term_t(term_t&& that) noexcept; public: postfix_expression(postfix_expression const& that); public: postfix_expression(postfix_expression&& that) noexcept; -#line 952 "reflect.h2" +#line 955 "reflect.h2" }; -#line 958 "reflect.h2" +#line 961 "reflect.h2" class template_arg : public reflection_base { -#line 962 "reflect.h2" +#line 965 "reflect.h2" public: template_arg( template_argument* n_, cpp2::impl::in s ); -#line 971 "reflect.h2" +#line 974 "reflect.h2" public: [[nodiscard]] auto is_expression() const& -> bool; public: [[nodiscard]] auto is_type_id() const& -> bool; @@ -860,47 +863,47 @@ class template_arg public: template_arg(template_arg const& that); public: template_arg(template_arg&& that) noexcept; -#line 978 "reflect.h2" +#line 981 "reflect.h2" }; -#line 984 "reflect.h2" +#line 987 "reflect.h2" class unqualified_id : public reflection_base { -#line 988 "reflect.h2" +#line 991 "reflect.h2" public: unqualified_id( unqualified_id_node* n_, cpp2::impl::in s ); -#line 997 "reflect.h2" +#line 1000 "reflect.h2" public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto get_identifier() const& -> std::string; -#line 1007 "reflect.h2" +#line 1010 "reflect.h2" public: [[nodiscard]] auto as_token() const& -> std::string; public: [[nodiscard]] auto to_string() const& -> std::string; public: unqualified_id(unqualified_id const& that); public: unqualified_id(unqualified_id&& that) noexcept; -#line 1010 "reflect.h2" +#line 1013 "reflect.h2" }; -#line 1016 "reflect.h2" +#line 1019 "reflect.h2" class qualified_id : public reflection_base { -#line 1020 "reflect.h2" +#line 1023 "reflect.h2" public: qualified_id( qualified_id_node* n_, cpp2::impl::in s ); -#line 1029 "reflect.h2" +#line 1032 "reflect.h2" public: class term_t { private: std::string op; private: unqualified_id unqualified; @@ -912,33 +915,33 @@ class qualified_id public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 1037 "reflect.h2" +#line 1040 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 1051 "reflect.h2" +#line 1054 "reflect.h2" public: [[nodiscard]] auto as_token() const& -> std::string; public: [[nodiscard]] auto to_string() const& -> std::string; public: qualified_id(qualified_id const& that); public: qualified_id(qualified_id&& that) noexcept; -#line 1054 "reflect.h2" +#line 1057 "reflect.h2" }; -#line 1060 "reflect.h2" +#line 1063 "reflect.h2" class type_id : public reflection_base { -#line 1064 "reflect.h2" +#line 1067 "reflect.h2" public: type_id( type_id_node* n_, cpp2::impl::in s ); -#line 1079 "reflect.h2" +#line 1082 "reflect.h2" public: [[nodiscard]] auto is_postfix_expression() const& -> bool; public: [[nodiscard]] auto is_qualified_id() const& -> bool; public: [[nodiscard]] auto is_unqualified_id() const& -> bool; @@ -952,7 +955,7 @@ class type_id public: [[nodiscard]] auto as_qualified_id() const& -> qualified_id; public: [[nodiscard]] auto as_unqualified_id() const& -> unqualified_id; -#line 1093 "reflect.h2" +#line 1096 "reflect.h2" public: [[nodiscard]] auto as_keyword() const& -> std::string; public: [[nodiscard]] auto as_token() const& -> std::string; @@ -960,21 +963,21 @@ class type_id public: type_id(type_id const& that); public: type_id(type_id&& that) noexcept; -#line 1097 "reflect.h2" +#line 1100 "reflect.h2" }; -#line 1103 "reflect.h2" +#line 1106 "reflect.h2" class primary_expression : public reflection_base { -#line 1107 "reflect.h2" +#line 1110 "reflect.h2" public: primary_expression( primary_expression_node* n_, cpp2::impl::in s ); -#line 1122 "reflect.h2" +#line 1125 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -992,21 +995,21 @@ class primary_expression public: primary_expression(primary_expression const& that); public: primary_expression(primary_expression&& that) noexcept; -#line 1136 "reflect.h2" +#line 1139 "reflect.h2" }; -#line 1142 "reflect.h2" +#line 1145 "reflect.h2" class id_expression : public reflection_base { -#line 1146 "reflect.h2" +#line 1149 "reflect.h2" public: id_expression( id_expression_node* n_, cpp2::impl::in s ); -#line 1161 "reflect.h2" +#line 1164 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_empty() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; @@ -1022,21 +1025,21 @@ class id_expression public: id_expression(id_expression const& that); public: id_expression(id_expression&& that) noexcept; -#line 1172 "reflect.h2" +#line 1175 "reflect.h2" }; -#line 1178 "reflect.h2" +#line 1181 "reflect.h2" class expression : public reflection_base { -#line 1182 "reflect.h2" +#line 1185 "reflect.h2" public: expression( expression_node* n_, cpp2::impl::in s ); -#line 1191 "reflect.h2" +#line 1194 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_standalone_expression() const& -> bool; public: [[nodiscard]] auto subexpression_count() const& -> int; @@ -1053,10 +1056,10 @@ struct get_lhs_rhs_if_simple_assignment_ret { postfix_expression lhs; logical_or -#line 1207 "reflect.h2" +#line 1210 "reflect.h2" public: [[nodiscard]] auto get_lhs_rhs_if_simple_assignment() const& -> get_lhs_rhs_if_simple_assignment_ret; -#line 1218 "reflect.h2" +#line 1221 "reflect.h2" public: [[nodiscard]] auto as_assignment_expression() const& -> assignment_expression; public: [[nodiscard]] auto as_expression_list() const& -> expression_list; public: [[nodiscard]] auto as_literal() const& -> std::string; @@ -1066,21 +1069,21 @@ struct get_lhs_rhs_if_simple_assignment_ret { postfix_expression lhs; logical_or public: expression(expression const& that); public: expression(expression&& that) noexcept; -#line 1223 "reflect.h2" +#line 1226 "reflect.h2" }; -#line 1229 "reflect.h2" +#line 1232 "reflect.h2" class is_as_expression : public reflection_base { -#line 1233 "reflect.h2" +#line 1236 "reflect.h2" public: is_as_expression( is_as_expression_node* n_, cpp2::impl::in s ); -#line 1242 "reflect.h2" +#line 1245 "reflect.h2" public: class term_t { private: std::string op; private: expression expr; @@ -1092,14 +1095,14 @@ class is_as_expression public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 1250 "reflect.h2" +#line 1253 "reflect.h2" }; public: [[nodiscard]] auto get_expression() const& -> prefix_expression; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 1260 "reflect.h2" +#line 1263 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -1112,27 +1115,27 @@ public: term_t(term_t&& that) noexcept; public: [[nodiscard]] auto get_identifier() const& -> std::string_view; -#line 1276 "reflect.h2" +#line 1279 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: virtual ~is_as_expression() noexcept; public: is_as_expression(is_as_expression const& that); public: is_as_expression(is_as_expression&& that) noexcept; -#line 1277 "reflect.h2" +#line 1280 "reflect.h2" }; -#line 1290 "reflect.h2" +#line 1293 "reflect.h2" class statement : public reflection_base { -#line 1294 "reflect.h2" +#line 1297 "reflect.h2" public: statement( statement_node* n_, cpp2::impl::in s ); -#line 1303 "reflect.h2" +#line 1306 "reflect.h2" public: [[nodiscard]] auto is_expression_statement() const& -> bool; public: [[nodiscard]] auto is_compound_statement() const& -> bool; public: [[nodiscard]] auto is_selection_statement() const& -> bool; @@ -1151,71 +1154,71 @@ class statement public: [[nodiscard]] auto as_return_statement() const& -> return_statement; public: [[nodiscard]] auto as_iteration_statement() const& -> iteration_statement; -#line 1325 "reflect.h2" +#line 1328 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: virtual ~statement() noexcept; public: statement(statement const& that); public: statement(statement&& that) noexcept; -#line 1326 "reflect.h2" +#line 1329 "reflect.h2" }; -#line 1332 "reflect.h2" +#line 1335 "reflect.h2" class expression_statement : public reflection_base { -#line 1336 "reflect.h2" +#line 1339 "reflect.h2" public: expression_statement( expression_statement_node* n_, cpp2::impl::in s ); -#line 1345 "reflect.h2" +#line 1348 "reflect.h2" public: [[nodiscard]] auto get_expression() const& -> expression; public: [[nodiscard]] auto to_string() const& -> std::string; public: expression_statement(expression_statement const& that); public: expression_statement(expression_statement&& that) noexcept; -#line 1348 "reflect.h2" +#line 1351 "reflect.h2" }; -#line 1354 "reflect.h2" +#line 1357 "reflect.h2" class compound_statement : public reflection_base { -#line 1358 "reflect.h2" +#line 1361 "reflect.h2" public: compound_statement( compound_statement_node* n_, cpp2::impl::in s ); -#line 1367 "reflect.h2" +#line 1370 "reflect.h2" public: [[nodiscard]] auto get_statements() const& -> std::vector; -#line 1377 "reflect.h2" +#line 1380 "reflect.h2" public: auto add_statement(cpp2::impl::in source, cpp2::impl::in before_position = 0) & -> void; public: compound_statement(compound_statement const& that); public: compound_statement(compound_statement&& that) noexcept; -#line 1387 "reflect.h2" +#line 1390 "reflect.h2" }; -#line 1393 "reflect.h2" +#line 1396 "reflect.h2" class selection_statement : public reflection_base { -#line 1397 "reflect.h2" +#line 1400 "reflect.h2" public: selection_statement( selection_statement_node* n_, cpp2::impl::in s ); -#line 1406 "reflect.h2" +#line 1409 "reflect.h2" public: [[nodiscard]] auto has_false_branch_in_source_code() const& -> bool; public: [[nodiscard]] auto has_false_branch() const& -> bool; @@ -1226,42 +1229,42 @@ class selection_statement public: selection_statement(selection_statement const& that); public: selection_statement(selection_statement&& that) noexcept; -#line 1413 "reflect.h2" +#line 1416 "reflect.h2" }; -#line 1419 "reflect.h2" +#line 1422 "reflect.h2" class return_statement : public reflection_base { -#line 1423 "reflect.h2" +#line 1426 "reflect.h2" public: return_statement( return_statement_node* n_, cpp2::impl::in s ); -#line 1432 "reflect.h2" +#line 1435 "reflect.h2" public: [[nodiscard]] auto has_expression() const& -> bool; public: [[nodiscard]] auto get_expression() const& -> expression; public: return_statement(return_statement const& that); public: return_statement(return_statement&& that) noexcept; -#line 1435 "reflect.h2" +#line 1438 "reflect.h2" }; -#line 1441 "reflect.h2" +#line 1444 "reflect.h2" class iteration_statement : public reflection_base { -#line 1445 "reflect.h2" +#line 1448 "reflect.h2" public: iteration_statement( iteration_statement_node* n_, cpp2::impl::in s ); -#line 1454 "reflect.h2" +#line 1457 "reflect.h2" public: [[nodiscard]] auto is_do() const& -> bool; public: [[nodiscard]] auto is_while() const& -> bool; public: [[nodiscard]] auto is_for() const& -> bool; @@ -1277,68 +1280,68 @@ class iteration_statement public: iteration_statement(iteration_statement const& that); public: iteration_statement(iteration_statement&& that) noexcept; -#line 1466 "reflect.h2" +#line 1469 "reflect.h2" }; -#line 1481 "reflect.h2" +#line 1484 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 1501 "reflect.h2" +#line 1504 "reflect.h2" auto interface(meta::type_declaration& t) -> void; -#line 1549 "reflect.h2" +#line 1552 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void; -#line 1594 "reflect.h2" +#line 1597 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::impl::in ordering ) -> void; -#line 1623 "reflect.h2" +#line 1626 "reflect.h2" auto ordered(meta::type_declaration& t) -> void; -#line 1631 "reflect.h2" +#line 1634 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void; -#line 1639 "reflect.h2" +#line 1642 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void; -#line 1661 "reflect.h2" +#line 1664 "reflect.h2" auto copyable(meta::type_declaration& t) -> void; -#line 1693 "reflect.h2" +#line 1696 "reflect.h2" auto copy_constructible(meta::type_declaration& t) -> void; -#line 1725 "reflect.h2" +#line 1728 "reflect.h2" auto hashable(meta::type_declaration& t) -> void; -#line 1758 "reflect.h2" +#line 1761 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void; -#line 1786 "reflect.h2" +#line 1789 "reflect.h2" auto value(meta::type_declaration& t) -> void; -#line 1792 "reflect.h2" +#line 1795 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 1798 "reflect.h2" +#line 1801 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 1827 "reflect.h2" +#line 1830 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void; -#line 1869 "reflect.h2" +#line 1872 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void; -#line 1938 "reflect.h2" +#line 1941 "reflect.h2" class value_member_info { public: std::string name; public: std::string type; public: std::string value; public: value_member_info(auto const& name_, auto const& type_, auto const& value_); -#line 1942 "reflect.h2" +#line 1945 "reflect.h2" }; auto basic_enum( @@ -1347,301 +1350,301 @@ auto basic_enum( cpp2::impl::in bitwise ) -> void; -#line 2208 "reflect.h2" +#line 2211 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void; -#line 2235 "reflect.h2" +#line 2238 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void; -#line 2281 "reflect.h2" +#line 2284 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void; -#line 2432 "reflect.h2" +#line 2435 "reflect.h2" auto print(cpp2::impl::in t) -> void; -#line 2443 "reflect.h2" +#line 2446 "reflect.h2" auto noisy(cpp2::impl::in t) -> void; -#line 2464 "reflect.h2" +#line 2467 "reflect.h2" auto sample_print(cpp2::impl::in s, cpp2::impl::in indent) -> void; -#line 2472 "reflect.h2" +#line 2475 "reflect.h2" class simple_traverser { public: virtual auto pre_traverse(cpp2::impl::in decl) -> void; -#line 2478 "reflect.h2" +#line 2481 "reflect.h2" public: virtual auto traverse(cpp2::impl::in decl) -> void; -#line 2498 "reflect.h2" +#line 2501 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in f) -> void; -#line 2502 "reflect.h2" +#line 2505 "reflect.h2" public: virtual auto traverse(cpp2::impl::in f) -> void; -#line 2523 "reflect.h2" +#line 2526 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in o) -> void; -#line 2527 "reflect.h2" +#line 2530 "reflect.h2" public: virtual auto traverse(cpp2::impl::in o) -> void; -#line 2535 "reflect.h2" +#line 2538 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in t) -> void; -#line 2539 "reflect.h2" +#line 2542 "reflect.h2" public: virtual auto traverse(cpp2::impl::in t) -> void; -#line 2547 "reflect.h2" +#line 2550 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in t) -> void; -#line 2551 "reflect.h2" +#line 2554 "reflect.h2" public: virtual auto traverse(cpp2::impl::in t) -> void; -#line 2556 "reflect.h2" +#line 2559 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2560 "reflect.h2" +#line 2563 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2595 "reflect.h2" +#line 2598 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2599 "reflect.h2" +#line 2602 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2609 "reflect.h2" +#line 2612 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2613 "reflect.h2" +#line 2616 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2621 "reflect.h2" +#line 2624 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2625 "reflect.h2" +#line 2628 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2644 "reflect.h2" +#line 2647 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2648 "reflect.h2" +#line 2651 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2659 "reflect.h2" +#line 2662 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in expr) -> void; -#line 2665 "reflect.h2" +#line 2668 "reflect.h2" public: virtual auto traverse(cpp2::impl::in expr) -> void; -#line 2679 "reflect.h2" +#line 2682 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2696 "reflect.h2" +#line 2699 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2707 "reflect.h2" +#line 2710 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2724 "reflect.h2" +#line 2727 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2736 "reflect.h2" +#line 2739 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2753 "reflect.h2" +#line 2756 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2764 "reflect.h2" +#line 2767 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2781 "reflect.h2" +#line 2784 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2792 "reflect.h2" +#line 2795 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2809 "reflect.h2" +#line 2812 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2821 "reflect.h2" +#line 2824 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2838 "reflect.h2" +#line 2841 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2850 "reflect.h2" +#line 2853 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2867 "reflect.h2" +#line 2870 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2878 "reflect.h2" +#line 2881 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2895 "reflect.h2" +#line 2898 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2906 "reflect.h2" +#line 2909 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2923 "reflect.h2" +#line 2926 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2934 "reflect.h2" +#line 2937 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2951 "reflect.h2" +#line 2954 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2962 "reflect.h2" +#line 2965 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2979 "reflect.h2" +#line 2982 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2991 "reflect.h2" +#line 2994 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 3008 "reflect.h2" +#line 3011 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 3019 "reflect.h2" +#line 3022 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in isas) -> void; -#line 3035 "reflect.h2" +#line 3038 "reflect.h2" public: virtual auto traverse(cpp2::impl::in isas) -> void; -#line 3046 "reflect.h2" +#line 3049 "reflect.h2" public: virtual auto traverse(cpp2::impl::in exprs) -> void; -#line 3053 "reflect.h2" +#line 3056 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in prefix) -> void; -#line 3069 "reflect.h2" +#line 3072 "reflect.h2" public: virtual auto traverse(cpp2::impl::in prefix) -> void; -#line 3074 "reflect.h2" +#line 3077 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in postfix) -> void; -#line 3090 "reflect.h2" +#line 3093 "reflect.h2" public: virtual auto traverse(cpp2::impl::in postfix) -> void; -#line 3109 "reflect.h2" +#line 3112 "reflect.h2" public: virtual auto traverse(cpp2::impl::in uid) -> void; -#line 3115 "reflect.h2" +#line 3118 "reflect.h2" public: virtual auto traverse(cpp2::impl::in qid) -> void; -#line 3125 "reflect.h2" +#line 3128 "reflect.h2" public: virtual auto traverse(cpp2::impl::in tid) -> void; -#line 3142 "reflect.h2" +#line 3145 "reflect.h2" public: virtual auto traverse(cpp2::impl::in primary) -> void; -#line 3162 "reflect.h2" +#line 3165 "reflect.h2" public: virtual auto traverse(cpp2::impl::in idexpr) -> void; public: simple_traverser() = default; public: simple_traverser(simple_traverser const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(simple_traverser const&) -> void = delete; -#line 3177 "reflect.h2" +#line 3180 "reflect.h2" }; -#line 3190 "reflect.h2" +#line 3193 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; -#line 3212 "reflect.h2" +#line 3215 "reflect.h2" auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent = 0) -> void; -#line 3242 "reflect.h2" +#line 3245 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void; -#line 3252 "reflect.h2" +#line 3255 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3271 "reflect.h2" +#line 3274 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3290 "reflect.h2" +#line 3293 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3337 "reflect.h2" +#line 3340 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3354 "reflect.h2" +#line 3357 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3364 "reflect.h2" +#line 3367 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3396 "reflect.h2" +#line 3399 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void; -#line 3410 "reflect.h2" +#line 3413 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3440 "reflect.h2" +#line 3443 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3470 "reflect.h2" +#line 3473 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3500 "reflect.h2" +#line 3503 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3530 "reflect.h2" +#line 3533 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3560 "reflect.h2" +#line 3563 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3590 "reflect.h2" +#line 3593 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3620 "reflect.h2" +#line 3623 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3650 "reflect.h2" +#line 3653 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3680 "reflect.h2" +#line 3683 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3710 "reflect.h2" +#line 3713 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3740 "reflect.h2" +#line 3743 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3770 "reflect.h2" +#line 3773 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void; -#line 3796 "reflect.h2" +#line 3799 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void; -#line 3811 "reflect.h2" +#line 3814 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void; -#line 3835 "reflect.h2" +#line 3838 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void; -#line 3868 "reflect.h2" +#line 3871 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void; -#line 3879 "reflect.h2" +#line 3882 "reflect.h2" auto sample_traverser(cpp2::impl::in qid, cpp2::impl::in indent) -> void; -#line 3895 "reflect.h2" +#line 3898 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void; -#line 3912 "reflect.h2" +#line 3915 "reflect.h2" auto sample_traverser(cpp2::impl::in primary, cpp2::impl::in indent) -> void; -#line 3932 "reflect.h2" +#line 3935 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; -#line 3954 "reflect.h2" +#line 3957 "reflect.h2" class autodiff_special_func { public: std::string name; public: int n_args; @@ -1653,39 +1656,44 @@ class autodiff_special_func { public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = "", cpp2::impl::in code_higher_order_ = ""); -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" public: autodiff_special_func(autodiff_special_func const& that); -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" public: autodiff_special_func(autodiff_special_func&& that) noexcept; -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; -#line 3981 "reflect.h2" +#line 3984 "reflect.h2" }; class autodiff_declaration_stack_item { - public: std::string full_name; + public: std::string full_name; public: meta::type_or_namespace_declaration decl; + + public: std::vector diff_request {}; + public: std::vector diff_done {}; + + public: autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_); using lookup_declaration_ret = std::vector; -#line 3987 "reflect.h2" +#line 3998 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; - public: autodiff_declaration_stack_item(auto&& full_name_, auto&& decl_) -CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; + public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); +public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 3996 "reflect.h2" +#line 4007 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4010 "reflect.h2" +#line 4021 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, true, false, "_rd_ = cos(_a1_) * _ad1_;\n" @@ -1711,11 +1719,11 @@ class autodiff_context { "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n")}; -#line 4036 "reflect.h2" +#line 4047 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4040 "reflect.h2" +#line 4051 "reflect.h2" public: std::string ad_type {"double"}; public: std::map> declaration_map {}; @@ -1723,44 +1731,59 @@ class autodiff_context { public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4062 "reflect.h2" +#line 4073 "reflect.h2" public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4073 "reflect.h2" +#line 4084 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4081 "reflect.h2" +#line 4092 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4090 "reflect.h2" +#line 4101 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; using lookup_function_declaration_ret = std::vector; -#line 4113 "reflect.h2" +#line 4124 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4123 "reflect.h2" +#line 4134 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4142 "reflect.h2" +#line 4153 "reflect.h2" + public: auto add_as_differentiated(cpp2::impl::in t) & -> void; + +#line 4161 "reflect.h2" + public: auto add_for_differentiation(cpp2::impl::in t) & -> void; + +#line 4181 "reflect.h2" + public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; + +#line 4191 "reflect.h2" public: auto enter_function() & -> void; -#line 4146 "reflect.h2" +#line 4195 "reflect.h2" public: auto leave_function() & -> void; + +#line 4198 "reflect.h2" + public: auto pop_stack() & -> void; + +#line 4215 "reflect.h2" + public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4148 "reflect.h2" +#line 4220 "reflect.h2" }; class autodiff_handler_base { @@ -1769,21 +1792,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4155 "reflect.h2" +#line 4227 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4159 "reflect.h2" +#line 4231 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4162 "reflect.h2" +#line 4234 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4168 "reflect.h2" +#line 4240 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1792,180 +1815,180 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4185 "reflect.h2" +#line 4257 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4204 "reflect.h2" +#line 4276 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4213 "reflect.h2" +#line 4285 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4251 "reflect.h2" +#line 4323 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4371 "reflect.h2" +#line 4445 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4404 "reflect.h2" +#line 4478 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4408 "reflect.h2" +#line 4482 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4412 "reflect.h2" +#line 4486 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4416 "reflect.h2" +#line 4490 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4420 "reflect.h2" +#line 4494 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4424 "reflect.h2" +#line 4498 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4428 "reflect.h2" +#line 4502 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4432 "reflect.h2" +#line 4506 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4436 "reflect.h2" +#line 4510 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4440 "reflect.h2" +#line 4514 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4444 "reflect.h2" +#line 4518 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4448 "reflect.h2" +#line 4522 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4472 "reflect.h2" +#line 4546 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4529 "reflect.h2" +#line 4603 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4533 "reflect.h2" +#line 4607 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4538 "reflect.h2" +#line 4612 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4565 "reflect.h2" +#line 4639 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4596 "reflect.h2" +#line 4670 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4602 "reflect.h2" +#line 4676 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4611 "reflect.h2" +#line 4685 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4616 "reflect.h2" +#line 4690 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4621 "reflect.h2" +#line 4695 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4639 "reflect.h2" +#line 4713 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4644 "reflect.h2" +#line 4718 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4649 "reflect.h2" +#line 4723 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4654 "reflect.h2" +#line 4728 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4662 "reflect.h2" +#line 4736 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4678 "reflect.h2" +#line 4752 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4725 "reflect.h2" +#line 4799 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4736 "reflect.h2" +#line 4810 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4764 "reflect.h2" +#line 4838 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4769 "reflect.h2" +#line 4843 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4773 "reflect.h2" +#line 4847 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4777 "reflect.h2" +#line 4851 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4781 "reflect.h2" +#line 4855 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4785 "reflect.h2" +#line 4859 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4789 "reflect.h2" +#line 4863 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4793 "reflect.h2" +#line 4867 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4797 "reflect.h2" +#line 4871 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4801 "reflect.h2" +#line 4875 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4805 "reflect.h2" +#line 4879 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4809 "reflect.h2" +#line 4883 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4813 "reflect.h2" +#line 4887 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4817 "reflect.h2" +#line 4891 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4822 "reflect.h2" +#line 4896 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4851 "reflect.h2" +#line 4925 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4855 "reflect.h2" +#line 4929 "reflect.h2" }; auto autodiff(meta::type_declaration& t) -> void; -#line 4979 "reflect.h2" +#line 5059 "reflect.h2" using error_func = std::function x)>; -#line 4983 "reflect.h2" +#line 5063 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2000,20 +2023,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 4991 "reflect.h2" +#line 5071 "reflect.h2" }; -#line 4999 "reflect.h2" +#line 5079 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5007 "reflect.h2" +#line 5087 "reflect.h2" public: explicit regex_token(); -#line 5012 "reflect.h2" +#line 5092 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2025,103 +2048,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5018 "reflect.h2" +#line 5098 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5024 "reflect.h2" +#line 5104 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5030 "reflect.h2" +#line 5110 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5037 "reflect.h2" +#line 5117 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5041 "reflect.h2" +#line 5121 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5042 "reflect.h2" +#line 5122 "reflect.h2" }; -#line 5045 "reflect.h2" +#line 5125 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5051 "reflect.h2" +#line 5131 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5058 "reflect.h2" +#line 5138 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5062 "reflect.h2" +#line 5142 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5063 "reflect.h2" +#line 5143 "reflect.h2" }; -#line 5066 "reflect.h2" +#line 5146 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5072 "reflect.h2" +#line 5152 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5076 "reflect.h2" +#line 5156 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5080 "reflect.h2" +#line 5160 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5081 "reflect.h2" +#line 5161 "reflect.h2" }; -#line 5084 "reflect.h2" +#line 5164 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5090 "reflect.h2" +#line 5170 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5097 "reflect.h2" +#line 5177 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5103 "reflect.h2" +#line 5183 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5109 "reflect.h2" +#line 5189 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5117 "reflect.h2" +#line 5197 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2129,10 +2152,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5129 "reflect.h2" +#line 5209 "reflect.h2" }; -#line 5132 "reflect.h2" +#line 5212 "reflect.h2" // // Parse and generation context. // @@ -2148,33 +2171,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5152 "reflect.h2" +#line 5232 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5159 "reflect.h2" +#line 5239 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5171 "reflect.h2" +#line 5251 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5176 "reflect.h2" +#line 5256 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5180 "reflect.h2" +#line 5260 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5194 "reflect.h2" +#line 5274 "reflect.h2" }; -#line 5197 "reflect.h2" +#line 5277 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2187,25 +2210,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5215 "reflect.h2" +#line 5295 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5221 "reflect.h2" +#line 5301 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5228 "reflect.h2" +#line 5308 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5235 "reflect.h2" +#line 5315 "reflect.h2" }; -#line 5238 "reflect.h2" +#line 5318 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2221,7 +2244,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5254 "reflect.h2" +#line 5334 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2229,64 +2252,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5265 "reflect.h2" +#line 5345 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5278 "reflect.h2" +#line 5358 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5286 "reflect.h2" +#line 5366 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5290 "reflect.h2" +#line 5370 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5294 "reflect.h2" +#line 5374 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5306 "reflect.h2" +#line 5386 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5313 "reflect.h2" +#line 5393 "reflect.h2" public: auto next_alternative() & -> void; -#line 5319 "reflect.h2" +#line 5399 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5325 "reflect.h2" +#line 5405 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5329 "reflect.h2" +#line 5409 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5340 "reflect.h2" +#line 5420 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5344 "reflect.h2" +#line 5424 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5350 "reflect.h2" +#line 5430 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5354 "reflect.h2" +#line 5434 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5361 "reflect.h2" +#line 5441 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5372 "reflect.h2" +#line 5452 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2294,51 +2317,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5416 "reflect.h2" +#line 5496 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5428 "reflect.h2" +#line 5508 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5441 "reflect.h2" +#line 5521 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5464 "reflect.h2" +#line 5544 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5481 "reflect.h2" +#line 5561 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5502 "reflect.h2" +#line 5582 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5512 "reflect.h2" +#line 5592 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5516 "reflect.h2" +#line 5596 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5572 "reflect.h2" +#line 5652 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5611 "reflect.h2" +#line 5691 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5626 "reflect.h2" +#line 5706 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2350,10 +2373,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5637 "reflect.h2" +#line 5717 "reflect.h2" }; -#line 5640 "reflect.h2" +#line 5720 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2363,16 +2386,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5654 "reflect.h2" +#line 5734 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5657 "reflect.h2" +#line 5737 "reflect.h2" }; -#line 5660 "reflect.h2" +#line 5740 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2392,68 +2415,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5682 "reflect.h2" +#line 5762 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5688 "reflect.h2" +#line 5768 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5697 "reflect.h2" +#line 5777 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5708 "reflect.h2" +#line 5788 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5715 "reflect.h2" +#line 5795 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5735 "reflect.h2" +#line 5815 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5745 "reflect.h2" +#line 5825 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5768 "reflect.h2" +#line 5848 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5776 "reflect.h2" +#line 5856 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5780 "reflect.h2" +#line 5860 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5786 "reflect.h2" +#line 5866 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5792 "reflect.h2" +#line 5872 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5802 "reflect.h2" +#line 5882 "reflect.h2" public: auto finish_context() & -> void; -#line 5810 "reflect.h2" +#line 5890 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5816 "reflect.h2" +#line 5896 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5820 "reflect.h2" +#line 5900 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5824 "reflect.h2" +#line 5904 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5848 "reflect.h2" +#line 5928 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2461,7 +2484,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5854 "reflect.h2" +#line 5934 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2481,27 +2504,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5873 "reflect.h2" +#line 5953 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5879 "reflect.h2" +#line 5959 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5886 "reflect.h2" +#line 5966 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5903 "reflect.h2" +#line 5983 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5910 "reflect.h2" +#line 5990 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 5923 "reflect.h2" +#line 6003 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2509,19 +2532,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 5935 "reflect.h2" +#line 6015 "reflect.h2" }; -#line 5938 "reflect.h2" +#line 6018 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 5944 "reflect.h2" +#line 6024 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 5948 "reflect.h2" +#line 6028 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2529,7 +2552,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 5953 "reflect.h2" +#line 6033 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2537,17 +2560,17 @@ class any_token class atomic_group_token : public regex_token { -#line 5961 "reflect.h2" +#line 6041 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 5972 "reflect.h2" +#line 6052 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5980 "reflect.h2" +#line 6060 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2555,7 +2578,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 5983 "reflect.h2" +#line 6063 "reflect.h2" }; // Regex syntax: a @@ -2563,34 +2586,34 @@ class atomic_group_token class char_token : public regex_token { -#line 5991 "reflect.h2" +#line 6071 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6000 "reflect.h2" +#line 6080 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6006 "reflect.h2" +#line 6086 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6010 "reflect.h2" +#line 6090 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6033 "reflect.h2" +#line 6113 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6054 "reflect.h2" +#line 6134 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6072 "reflect.h2" +#line 6152 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6087 "reflect.h2" +#line 6167 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6093 "reflect.h2" +#line 6173 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2598,33 +2621,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6097 "reflect.h2" +#line 6177 "reflect.h2" }; -#line 6100 "reflect.h2" +#line 6180 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6106 "reflect.h2" +#line 6186 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6118 "reflect.h2" +#line 6198 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6244 "reflect.h2" +#line 6324 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6253 "reflect.h2" +#line 6333 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6258 "reflect.h2" +#line 6338 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2632,20 +2655,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6265 "reflect.h2" +#line 6345 "reflect.h2" }; -#line 6268 "reflect.h2" +#line 6348 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6309 "reflect.h2" +#line 6389 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6320 "reflect.h2" +#line 6400 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2655,20 +2678,20 @@ class class_token class group_ref_token : public regex_token { -#line 6330 "reflect.h2" +#line 6410 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6342 "reflect.h2" +#line 6422 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6443 "reflect.h2" +#line 6523 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6447 "reflect.h2" +#line 6527 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2676,10 +2699,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6450 "reflect.h2" +#line 6530 "reflect.h2" }; -#line 6453 "reflect.h2" +#line 6533 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2693,29 +2716,29 @@ class group_ref_token class group_token : public regex_token { -#line 6467 "reflect.h2" +#line 6547 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6489 "reflect.h2" +#line 6569 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6503 "reflect.h2" +#line 6583 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6662 "reflect.h2" +#line 6742 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6670 "reflect.h2" +#line 6750 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6688 "reflect.h2" +#line 6768 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6719 "reflect.h2" +#line 6799 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2724,25 +2747,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6726 "reflect.h2" +#line 6806 "reflect.h2" }; -#line 6729 "reflect.h2" +#line 6809 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6770 "reflect.h2" +#line 6850 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6790 "reflect.h2" +#line 6870 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6806 "reflect.h2" +#line 6886 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2750,20 +2773,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6814 "reflect.h2" +#line 6894 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6823 "reflect.h2" +#line 6903 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6834 "reflect.h2" +#line 6914 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6841 "reflect.h2" +#line 6921 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2771,26 +2794,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6844 "reflect.h2" +#line 6924 "reflect.h2" }; -#line 6847 "reflect.h2" +#line 6927 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6875 "reflect.h2" +#line 6955 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6903 "reflect.h2" +#line 6983 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6909 "reflect.h2" +#line 6989 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2800,22 +2823,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6989 "reflect.h2" +#line 7069 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7001 "reflect.h2" +#line 7081 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7014 "reflect.h2" +#line 7094 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7033 "reflect.h2" +#line 7113 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7043 "reflect.h2" +#line 7123 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7054 "reflect.h2" +#line 7134 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2823,16 +2846,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7057 "reflect.h2" +#line 7137 "reflect.h2" }; -#line 7060 "reflect.h2" +#line 7140 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7066 "reflect.h2" +#line 7146 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2841,7 +2864,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7096 "reflect.h2" +#line 7176 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2850,14 +2873,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7118 "reflect.h2" +#line 7198 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7140 "reflect.h2" +#line 7220 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2878,24 +2901,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7163 "reflect.h2" +#line 7243 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7198 "reflect.h2" +#line 7278 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7212 "reflect.h2" +#line 7292 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7224 "reflect.h2" +#line 7304 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7279 "reflect.h2" +#line 7359 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2906,7 +2929,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7405 "reflect.h2" +#line 7485 "reflect.h2" } } @@ -3144,15 +3167,20 @@ compiler_services::compiler_services(compiler_services&& that) noexcept #line 208 "reflect.h2" template [[nodiscard]] auto reflection_base::print() const& -> std::string { return CPP2_UFCS(pretty_print_visualize)((*cpp2::impl::assert_not_null(n)), 0); } +#line 210 "reflect.h2" + template [[nodiscard]] auto reflection_base::is_same(cpp2::impl::in o) const& -> bool { return n == o.n; }// Test pointers +#line 211 "reflect.h2" + template template [[nodiscard]] auto reflection_base::is_same(reflection_base const& o) const& -> bool { return false; } + template reflection_base::~reflection_base() noexcept{} template reflection_base::reflection_base(reflection_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} template reflection_base::reflection_base(reflection_base&& that) noexcept : compiler_services{ static_cast(that) } - , n{ std::move(that).n }{} + , n{ std::move(that).n }{}// Different types => false -#line 212 "reflect.h2" +#line 215 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -3164,126 +3192,126 @@ template reflection_base::reflection_base(reflection_base&& that // All declarations // -#line 226 "reflect.h2" +#line 229 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 231 "reflect.h2" +#line 234 "reflect.h2" { } -#line 235 "reflect.h2" +#line 238 "reflect.h2" [[nodiscard]] auto declaration::is_public() const& -> bool { return CPP2_UFCS(is_public)((*cpp2::impl::assert_not_null(n))); } -#line 236 "reflect.h2" +#line 239 "reflect.h2" [[nodiscard]] auto declaration::is_protected() const& -> bool { return CPP2_UFCS(is_protected)((*cpp2::impl::assert_not_null(n))); } -#line 237 "reflect.h2" +#line 240 "reflect.h2" [[nodiscard]] auto declaration::is_private() const& -> bool { return CPP2_UFCS(is_private)((*cpp2::impl::assert_not_null(n))); } -#line 238 "reflect.h2" +#line 241 "reflect.h2" [[nodiscard]] auto declaration::is_default_access() const& -> bool { return CPP2_UFCS(is_default_access)((*cpp2::impl::assert_not_null(n))); } -#line 240 "reflect.h2" +#line 243 "reflect.h2" [[nodiscard]] auto declaration::default_to_public() & -> decltype(auto) { return static_cast(CPP2_UFCS(make_public)((*cpp2::impl::assert_not_null(n)))); } -#line 241 "reflect.h2" +#line 244 "reflect.h2" [[nodiscard]] auto declaration::default_to_protected() & -> decltype(auto) { return static_cast(CPP2_UFCS(make_protected)((*cpp2::impl::assert_not_null(n)))); } -#line 242 "reflect.h2" +#line 245 "reflect.h2" [[nodiscard]] auto declaration::default_to_private() & -> decltype(auto) { return static_cast(CPP2_UFCS(make_private)((*cpp2::impl::assert_not_null(n)))); } -#line 244 "reflect.h2" +#line 247 "reflect.h2" [[nodiscard]] auto declaration::make_public() & -> bool { return CPP2_UFCS(make_public)((*cpp2::impl::assert_not_null(n))); } -#line 245 "reflect.h2" +#line 248 "reflect.h2" [[nodiscard]] auto declaration::make_protected() & -> bool { return CPP2_UFCS(make_protected)((*cpp2::impl::assert_not_null(n))); } -#line 246 "reflect.h2" +#line 249 "reflect.h2" [[nodiscard]] auto declaration::make_private() & -> bool { return CPP2_UFCS(make_private)((*cpp2::impl::assert_not_null(n))); } -#line 248 "reflect.h2" +#line 251 "reflect.h2" [[nodiscard]] auto declaration::has_name() const& -> bool { return CPP2_UFCS(has_name)((*cpp2::impl::assert_not_null(n))); } -#line 249 "reflect.h2" +#line 252 "reflect.h2" [[nodiscard]] auto declaration::has_name(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_name)((*cpp2::impl::assert_not_null(n)), s); } -#line 251 "reflect.h2" +#line 254 "reflect.h2" [[nodiscard]] auto declaration::name() const& -> std::string_view{ if (has_name()) {return CPP2_UFCS(as_string_view)((*cpp2::impl::assert_not_null(CPP2_UFCS(name)(*cpp2::impl::assert_not_null(n))))); } else { return ""; } } -#line 256 "reflect.h2" +#line 259 "reflect.h2" [[nodiscard]] auto declaration::has_initializer() const& -> bool { return CPP2_UFCS(has_initializer)((*cpp2::impl::assert_not_null(n))); } -#line 258 "reflect.h2" +#line 261 "reflect.h2" [[nodiscard]] auto declaration::get_initializer() const& -> statement { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).initializer), (*this) }; } -#line 260 "reflect.h2" +#line 263 "reflect.h2" [[nodiscard]] auto declaration::is_global() const& -> bool { return CPP2_UFCS(is_global)((*cpp2::impl::assert_not_null(n))); } -#line 261 "reflect.h2" +#line 264 "reflect.h2" [[nodiscard]] auto declaration::is_function() const& -> bool { return CPP2_UFCS(is_function)((*cpp2::impl::assert_not_null(n))); } -#line 262 "reflect.h2" +#line 265 "reflect.h2" [[nodiscard]] auto declaration::is_object() const& -> bool { return CPP2_UFCS(is_object)((*cpp2::impl::assert_not_null(n))); } -#line 263 "reflect.h2" +#line 266 "reflect.h2" [[nodiscard]] auto declaration::is_base_object() const& -> bool { return CPP2_UFCS(is_base_object)((*cpp2::impl::assert_not_null(n))); } -#line 264 "reflect.h2" +#line 267 "reflect.h2" [[nodiscard]] auto declaration::is_member_object() const& -> bool { return CPP2_UFCS(is_member_object)((*cpp2::impl::assert_not_null(n))); } -#line 265 "reflect.h2" +#line 268 "reflect.h2" [[nodiscard]] auto declaration::is_type() const& -> bool { return CPP2_UFCS(is_type)((*cpp2::impl::assert_not_null(n))); } -#line 266 "reflect.h2" +#line 269 "reflect.h2" [[nodiscard]] auto declaration::is_namespace() const& -> bool { return CPP2_UFCS(is_namespace)((*cpp2::impl::assert_not_null(n))); } -#line 267 "reflect.h2" +#line 270 "reflect.h2" [[nodiscard]] auto declaration::is_alias() const& -> bool { return CPP2_UFCS(is_alias)((*cpp2::impl::assert_not_null(n))); } -#line 269 "reflect.h2" +#line 272 "reflect.h2" [[nodiscard]] auto declaration::is_type_alias() const& -> bool { return CPP2_UFCS(is_type_alias)((*cpp2::impl::assert_not_null(n))); } -#line 270 "reflect.h2" +#line 273 "reflect.h2" [[nodiscard]] auto declaration::is_namespace_alias() const& -> bool { return CPP2_UFCS(is_namespace_alias)((*cpp2::impl::assert_not_null(n))); } -#line 271 "reflect.h2" +#line 274 "reflect.h2" [[nodiscard]] auto declaration::is_object_alias() const& -> bool { return CPP2_UFCS(is_object_alias)((*cpp2::impl::assert_not_null(n))); } -#line 273 "reflect.h2" +#line 276 "reflect.h2" [[nodiscard]] auto declaration::is_function_expression() const& -> bool { return CPP2_UFCS(is_function_expression)((*cpp2::impl::assert_not_null(n))); } -#line 275 "reflect.h2" +#line 278 "reflect.h2" [[nodiscard]] auto declaration::as_function() const& -> function_declaration { return { n, (*this) }; } -#line 276 "reflect.h2" +#line 279 "reflect.h2" [[nodiscard]] auto declaration::as_object() const& -> object_declaration { return { n, (*this) }; } -#line 277 "reflect.h2" +#line 280 "reflect.h2" [[nodiscard]] auto declaration::as_type() const& -> type_declaration { return { n, (*this) }; } -#line 278 "reflect.h2" +#line 281 "reflect.h2" [[nodiscard]] auto declaration::as_nonglobal_namespace() const& -> namespace_declaration { return { n, (*this) }; } -#line 279 "reflect.h2" +#line 282 "reflect.h2" [[nodiscard]] auto declaration::as_alias() const& -> alias_declaration { return { n, (*this) }; } -#line 281 "reflect.h2" +#line 284 "reflect.h2" [[nodiscard]] auto declaration::get_parent() const& -> declaration { return declaration((*cpp2::impl::assert_not_null(n)).parent_declaration, (*this)); } -#line 283 "reflect.h2" +#line 286 "reflect.h2" [[nodiscard]] auto declaration::parent_is_function() const& -> bool { return CPP2_UFCS(parent_is_function)((*cpp2::impl::assert_not_null(n))); } -#line 284 "reflect.h2" +#line 287 "reflect.h2" [[nodiscard]] auto declaration::parent_is_object() const& -> bool { return CPP2_UFCS(parent_is_object)((*cpp2::impl::assert_not_null(n))); } -#line 285 "reflect.h2" +#line 288 "reflect.h2" [[nodiscard]] auto declaration::parent_is_type() const& -> bool { return CPP2_UFCS(parent_is_type)((*cpp2::impl::assert_not_null(n))); } -#line 286 "reflect.h2" +#line 289 "reflect.h2" [[nodiscard]] auto declaration::parent_is_nonglobal_namespace() const& -> bool { return CPP2_UFCS(parent_is_nonglobal_namespace)((*cpp2::impl::assert_not_null(n))); } -#line 287 "reflect.h2" +#line 290 "reflect.h2" [[nodiscard]] auto declaration::parent_is_alias() const& -> bool { return CPP2_UFCS(parent_is_alias)((*cpp2::impl::assert_not_null(n))); } -#line 289 "reflect.h2" +#line 292 "reflect.h2" [[nodiscard]] auto declaration::parent_is_type_alias() const& -> bool { return CPP2_UFCS(parent_is_type_alias)((*cpp2::impl::assert_not_null(n))); } -#line 290 "reflect.h2" +#line 293 "reflect.h2" [[nodiscard]] auto declaration::parent_is_namespace_alias() const& -> bool { return CPP2_UFCS(parent_is_namespace_alias)((*cpp2::impl::assert_not_null(n))); } -#line 291 "reflect.h2" +#line 294 "reflect.h2" [[nodiscard]] auto declaration::parent_is_object_alias() const& -> bool { return CPP2_UFCS(parent_is_object_alias)((*cpp2::impl::assert_not_null(n))); } -#line 293 "reflect.h2" +#line 296 "reflect.h2" [[nodiscard]] auto declaration::parent_is_polymorphic() const& -> bool { return CPP2_UFCS(parent_is_polymorphic)((*cpp2::impl::assert_not_null(n))); } -#line 295 "reflect.h2" +#line 298 "reflect.h2" auto declaration::mark_for_removal_from_enclosing_type() & -> void // this precondition should be sufficient ... { if (cpp2::type_safety.is_active() && !(parent_is_type()) ) { cpp2::type_safety.report_violation(""); } -#line 298 "reflect.h2" +#line 301 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::impl::assert_not_null(n)))}; if (cpp2::cpp2_default.is_active() && !(cpp2::move(test)) ) { cpp2::cpp2_default.report_violation(""); }// ... to ensure this assert is true } @@ -3294,111 +3322,111 @@ declaration::declaration(declaration const& that) declaration::declaration(declaration&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 304 "reflect.h2" +#line 307 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // -#line 311 "reflect.h2" +#line 314 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::impl::in s ) : declaration{ n_, s } -#line 316 "reflect.h2" +#line 319 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_function)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } } -#line 321 "reflect.h2" +#line 324 "reflect.h2" [[nodiscard]] auto function_declaration::index_of_parameter_named(cpp2::impl::in s) const& -> int { return CPP2_UFCS(index_of_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 322 "reflect.h2" +#line 325 "reflect.h2" [[nodiscard]] auto function_declaration::has_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 323 "reflect.h2" +#line 326 "reflect.h2" [[nodiscard]] auto function_declaration::has_return_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_return_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 324 "reflect.h2" +#line 327 "reflect.h2" [[nodiscard]] auto function_declaration::has_parameter_or_return_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_parameter_or_return_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 325 "reflect.h2" +#line 328 "reflect.h2" [[nodiscard]] auto function_declaration::has_in_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_in_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 326 "reflect.h2" +#line 329 "reflect.h2" [[nodiscard]] auto function_declaration::has_in_ref_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_in_ref_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 327 "reflect.h2" +#line 330 "reflect.h2" [[nodiscard]] auto function_declaration::has_copy_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_copy_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 328 "reflect.h2" +#line 331 "reflect.h2" [[nodiscard]] auto function_declaration::has_inout_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_inout_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 329 "reflect.h2" +#line 332 "reflect.h2" [[nodiscard]] auto function_declaration::has_out_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_out_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 330 "reflect.h2" +#line 333 "reflect.h2" [[nodiscard]] auto function_declaration::has_move_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_move_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 331 "reflect.h2" +#line 334 "reflect.h2" [[nodiscard]] auto function_declaration::has_forward_parameter_named(cpp2::impl::in s) const& -> bool { return CPP2_UFCS(has_forward_parameter_named)((*cpp2::impl::assert_not_null(n)), s); } -#line 332 "reflect.h2" +#line 335 "reflect.h2" [[nodiscard]] auto function_declaration::first_parameter_name() const& -> std::string { return CPP2_UFCS(first_parameter_name)((*cpp2::impl::assert_not_null(n))); } -#line 334 "reflect.h2" +#line 337 "reflect.h2" [[nodiscard]] auto function_declaration::has_parameter_with_name_and_pass(cpp2::impl::in s, cpp2::impl::in pass) const& -> bool { return CPP2_UFCS(has_parameter_with_name_and_pass)((*cpp2::impl::assert_not_null(n)), s, pass); } -#line 336 "reflect.h2" +#line 339 "reflect.h2" [[nodiscard]] auto function_declaration::is_function_with_this() const& -> bool { return CPP2_UFCS(is_function_with_this)((*cpp2::impl::assert_not_null(n))); } -#line 337 "reflect.h2" +#line 340 "reflect.h2" [[nodiscard]] auto function_declaration::is_virtual() const& -> bool { return CPP2_UFCS(is_virtual_function)((*cpp2::impl::assert_not_null(n))); } -#line 338 "reflect.h2" +#line 341 "reflect.h2" [[nodiscard]] auto function_declaration::is_defaultable() const& -> bool { return CPP2_UFCS(is_defaultable_function)((*cpp2::impl::assert_not_null(n))); } -#line 339 "reflect.h2" +#line 342 "reflect.h2" [[nodiscard]] auto function_declaration::is_constructor() const& -> bool { return CPP2_UFCS(is_constructor)((*cpp2::impl::assert_not_null(n))); } -#line 340 "reflect.h2" +#line 343 "reflect.h2" [[nodiscard]] auto function_declaration::is_default_constructor() const& -> bool { return CPP2_UFCS(is_default_constructor)((*cpp2::impl::assert_not_null(n))); } -#line 341 "reflect.h2" +#line 344 "reflect.h2" [[nodiscard]] auto function_declaration::is_move() const& -> bool { return CPP2_UFCS(is_move)((*cpp2::impl::assert_not_null(n))); } -#line 342 "reflect.h2" +#line 345 "reflect.h2" [[nodiscard]] auto function_declaration::is_swap() const& -> bool { return CPP2_UFCS(is_swap)((*cpp2::impl::assert_not_null(n))); } -#line 343 "reflect.h2" +#line 346 "reflect.h2" [[nodiscard]] auto function_declaration::is_constructor_with_that() const& -> bool { return CPP2_UFCS(is_constructor_with_that)((*cpp2::impl::assert_not_null(n))); } -#line 344 "reflect.h2" +#line 347 "reflect.h2" [[nodiscard]] auto function_declaration::is_constructor_with_in_that() const& -> bool { return CPP2_UFCS(is_constructor_with_in_that)((*cpp2::impl::assert_not_null(n))); } -#line 345 "reflect.h2" +#line 348 "reflect.h2" [[nodiscard]] auto function_declaration::is_constructor_with_move_that() const& -> bool { return CPP2_UFCS(is_constructor_with_move_that)((*cpp2::impl::assert_not_null(n))); } -#line 346 "reflect.h2" +#line 349 "reflect.h2" [[nodiscard]] auto function_declaration::is_assignment() const& -> bool { return CPP2_UFCS(is_assignment)((*cpp2::impl::assert_not_null(n))); } -#line 347 "reflect.h2" +#line 350 "reflect.h2" [[nodiscard]] auto function_declaration::is_assignment_with_that() const& -> bool { return CPP2_UFCS(is_assignment_with_that)((*cpp2::impl::assert_not_null(n))); } -#line 348 "reflect.h2" +#line 351 "reflect.h2" [[nodiscard]] auto function_declaration::is_assignment_with_in_that() const& -> bool { return CPP2_UFCS(is_assignment_with_in_that)((*cpp2::impl::assert_not_null(n))); } -#line 349 "reflect.h2" +#line 352 "reflect.h2" [[nodiscard]] auto function_declaration::is_assignment_with_move_that() const& -> bool { return CPP2_UFCS(is_assignment_with_move_that)((*cpp2::impl::assert_not_null(n))); } -#line 350 "reflect.h2" +#line 353 "reflect.h2" [[nodiscard]] auto function_declaration::is_destructor() const& -> bool { return CPP2_UFCS(is_destructor)((*cpp2::impl::assert_not_null(n))); } -#line 352 "reflect.h2" +#line 355 "reflect.h2" [[nodiscard]] auto function_declaration::is_copy_or_move() const& -> bool { return is_constructor_with_that() || is_assignment_with_that(); } -#line 354 "reflect.h2" +#line 357 "reflect.h2" [[nodiscard]] auto function_declaration::has_declared_return_type() const& -> bool { return CPP2_UFCS(has_declared_return_type)((*cpp2::impl::assert_not_null(n))); } -#line 355 "reflect.h2" +#line 358 "reflect.h2" [[nodiscard]] auto function_declaration::has_deduced_return_type() const& -> bool { return CPP2_UFCS(has_deduced_return_type)((*cpp2::impl::assert_not_null(n))); } -#line 356 "reflect.h2" +#line 359 "reflect.h2" [[nodiscard]] auto function_declaration::has_bool_return_type() const& -> bool { return CPP2_UFCS(has_bool_return_type)((*cpp2::impl::assert_not_null(n))); } -#line 357 "reflect.h2" +#line 360 "reflect.h2" [[nodiscard]] auto function_declaration::has_non_void_return_type() const& -> bool { return CPP2_UFCS(has_non_void_return_type)((*cpp2::impl::assert_not_null(n))); } -#line 359 "reflect.h2" +#line 362 "reflect.h2" [[nodiscard]] auto function_declaration::has_compound_body() const& -> bool { return CPP2_UFCS(is_function_with_compound_body)((*cpp2::impl::assert_not_null(n))); } -#line 361 "reflect.h2" +#line 364 "reflect.h2" [[nodiscard]] auto function_declaration::get_body() const& -> statement { return { CPP2_UFCS(get_function_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 362 "reflect.h2" +#line 365 "reflect.h2" [[nodiscard]] auto function_declaration::get_compound_body() const& -> compound_statement { return { CPP2_UFCS(get_function_compound_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 363 "reflect.h2" +#line 366 "reflect.h2" [[nodiscard]] auto function_declaration::get_unnamed_return_type() const& -> std::string { return CPP2_UFCS(unnamed_return_type_to_string)((*cpp2::impl::assert_not_null(n))); } -#line 364 "reflect.h2" +#line 367 "reflect.h2" [[nodiscard]] auto function_declaration::get_signature() const& -> std::string { return CPP2_UFCS(signature_to_string)((*cpp2::impl::assert_not_null(n))); } -#line 366 "reflect.h2" +#line 369 "reflect.h2" [[nodiscard]] auto function_declaration::is_binary_comparison_function() const& -> bool { return CPP2_UFCS(is_binary_comparison_function)((*cpp2::impl::assert_not_null(n))); } -#line 368 "reflect.h2" +#line 371 "reflect.h2" [[nodiscard]] auto function_declaration::get_parameters() const& -> std::vector { @@ -3409,7 +3437,7 @@ declaration::declaration(declaration&& that) noexcept return ret; } -#line 378 "reflect.h2" +#line 381 "reflect.h2" [[nodiscard]] auto function_declaration::get_returns() const& -> std::vector { @@ -3422,20 +3450,20 @@ declaration::declaration(declaration&& that) noexcept // Modifying operations // -#line 390 "reflect.h2" +#line 393 "reflect.h2" [[nodiscard]] auto function_declaration::default_to_virtual() & -> decltype(auto) { return static_cast(CPP2_UFCS(make_function_virtual)((*cpp2::impl::assert_not_null(n)))); } -#line 392 "reflect.h2" +#line 395 "reflect.h2" [[nodiscard]] auto function_declaration::make_virtual() & -> bool { return CPP2_UFCS(make_function_virtual)((*cpp2::impl::assert_not_null(n))); } -#line 394 "reflect.h2" +#line 397 "reflect.h2" auto function_declaration::add_initializer(cpp2::impl::in source) & -> void -#line 397 "reflect.h2" +#line 400 "reflect.h2" { if ((*this).is_active() && !(!(has_initializer())) ) { (*this).report_violation(CPP2_CONTRACT_MSG("cannot add an initializer to a function that already has one")); } if ((*this).is_active() && !(parent_is_type()) ) { (*this).report_violation(CPP2_CONTRACT_MSG("cannot add an initializer to a function that isn't in a type scope")); } -#line 398 "reflect.h2" +#line 401 "reflect.h2" auto stmt {parse_statement(source)}; if (!((cpp2::impl::as_(stmt)))) { error("cannot add an initializer that is not a valid statement"); @@ -3450,30 +3478,30 @@ declaration::declaration(declaration&& that) noexcept function_declaration::function_declaration(function_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 409 "reflect.h2" +#line 412 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // -#line 416 "reflect.h2" +#line 419 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::impl::in s ) : declaration{ n_, s } -#line 421 "reflect.h2" +#line 424 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_object)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } } -#line 426 "reflect.h2" +#line 429 "reflect.h2" [[nodiscard]] auto object_declaration::is_const() const& -> bool { return CPP2_UFCS(is_const)((*cpp2::impl::assert_not_null(n))); } -#line 427 "reflect.h2" +#line 430 "reflect.h2" [[nodiscard]] auto object_declaration::has_wildcard_type() const& -> bool { return CPP2_UFCS(has_wildcard_type)((*cpp2::impl::assert_not_null(n))); } -#line 429 "reflect.h2" +#line 432 "reflect.h2" [[nodiscard]] auto object_declaration::type() const& -> std::string{ auto ret {CPP2_UFCS(object_type)((*cpp2::impl::assert_not_null(n)))}; require(!(contains(ret, "(*ERROR*)")), @@ -3481,7 +3509,7 @@ function_declaration::function_declaration(function_declaration&& that) noexcept return ret; } -#line 436 "reflect.h2" +#line 439 "reflect.h2" [[nodiscard]] auto object_declaration::initializer() const& -> std::string{ auto ret {CPP2_UFCS(object_initializer)((*cpp2::impl::assert_not_null(n)))}; require(!(contains(ret, "(*ERROR*)")), @@ -3494,25 +3522,25 @@ function_declaration::function_declaration(function_declaration&& that) noexcept object_declaration::object_declaration(object_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 445 "reflect.h2" +#line 448 "reflect.h2" //----------------------------------------------------------------------- // Type and namespace declarations // -#line 452 "reflect.h2" +#line 455 "reflect.h2" type_or_namespace_declaration::type_or_namespace_declaration( declaration_node* n_, cpp2::impl::in s ) : declaration{ n_, s } -#line 457 "reflect.h2" +#line 460 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_type)((*cpp2::impl::assert_not_null(n))) || CPP2_UFCS(is_namespace)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } } -#line 462 "reflect.h2" +#line 465 "reflect.h2" auto type_or_namespace_declaration::reserve_names(cpp2::impl::in name, auto&& ...etc) const& -> void { // etc is not declared ':string_view' for compatibility with GCC 10.x for ( @@ -3527,7 +3555,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept } } -#line 476 "reflect.h2" +#line 479 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_member_functions() const& -> std::vector { @@ -3539,7 +3567,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 487 "reflect.h2" +#line 490 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_member_functions_needing_initializer() const& -> std::vector { @@ -3555,7 +3583,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 502 "reflect.h2" +#line 505 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_member_objects() const& -> std::vector { @@ -3566,7 +3594,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 512 "reflect.h2" +#line 515 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_member_types() const& -> std::vector { @@ -3577,7 +3605,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 522 "reflect.h2" +#line 525 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_member_aliases() const& -> std::vector { @@ -3588,7 +3616,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 532 "reflect.h2" +#line 535 "reflect.h2" [[nodiscard]] auto type_or_namespace_declaration::get_members() const& -> std::vector { @@ -3599,7 +3627,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept return ret; } -#line 542 "reflect.h2" +#line 545 "reflect.h2" auto type_or_namespace_declaration::add_member(cpp2::impl::in source) & -> void { auto decl {parse_statement(source)}; @@ -3619,36 +3647,36 @@ object_declaration::object_declaration(object_declaration&& that) noexcept type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 562 "reflect.h2" +#line 565 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } -#line 567 "reflect.h2" +#line 570 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_type)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } } -#line 573 "reflect.h2" +#line 576 "reflect.h2" [[nodiscard]] auto type_declaration::is_polymorphic() const& -> bool { return CPP2_UFCS(is_polymorphic)((*cpp2::impl::assert_not_null(n))); } -#line 574 "reflect.h2" +#line 577 "reflect.h2" [[nodiscard]] auto type_declaration::is_final() const& -> bool { return CPP2_UFCS(is_type_final)((*cpp2::impl::assert_not_null(n))); } -#line 575 "reflect.h2" +#line 578 "reflect.h2" [[nodiscard]] auto type_declaration::make_final() & -> bool { return CPP2_UFCS(make_type_final)((*cpp2::impl::assert_not_null(n))); } -#line 577 "reflect.h2" +#line 580 "reflect.h2" [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 584 "reflect.h2" +#line 587 "reflect.h2" { cpp2::impl::deferred_init out_this_in_that; cpp2::impl::deferred_init out_this_move_that; cpp2::impl::deferred_init inout_this_in_that; cpp2::impl::deferred_init inout_this_move_that; -#line 585 "reflect.h2" +#line 588 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::impl::assert_not_null(n)))}; out_this_in_that.construct(declared.out_this_in_that != nullptr); out_this_move_that.construct(declared.out_this_move_that != nullptr); @@ -3657,13 +3685,13 @@ type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_d return { std::move(out_this_in_that.value()), std::move(out_this_move_that.value()), std::move(inout_this_in_that.value()), std::move(inout_this_move_that.value()) }; // NOLINT(performance-move-const-arg) } -#line 593 "reflect.h2" +#line 596 "reflect.h2" [[nodiscard]] auto type_declaration::disable_member_function_generation() & -> decltype(auto) { return CPP2_UFCS(type_disable_member_function_generation)((*cpp2::impl::assert_not_null(n))); } // At some point we may want to allow this also for namespaces, but for now only types -#line 596 "reflect.h2" +#line 599 "reflect.h2" [[nodiscard]] auto type_declaration::remove_marked_members() & -> decltype(auto) { return CPP2_UFCS(type_remove_marked_members)((*cpp2::impl::assert_not_null(n))); } -#line 597 "reflect.h2" +#line 600 "reflect.h2" [[nodiscard]] auto type_declaration::remove_all_members() & -> decltype(auto) { return CPP2_UFCS(type_remove_all_members)((*cpp2::impl::assert_not_null(n))); } type_declaration::type_declaration(type_declaration const& that) @@ -3671,14 +3699,14 @@ type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_d type_declaration::type_declaration(type_declaration&& that) noexcept : type_or_namespace_declaration{ static_cast(that) }{} -#line 605 "reflect.h2" +#line 608 "reflect.h2" namespace_declaration::namespace_declaration( declaration_node* n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } -#line 610 "reflect.h2" +#line 613 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_namespace)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } @@ -3689,19 +3717,19 @@ type_declaration::type_declaration(type_declaration&& that) noexcept namespace_declaration::namespace_declaration(namespace_declaration&& that) noexcept : type_or_namespace_declaration{ static_cast(that) }{} -#line 617 "reflect.h2" +#line 620 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // -#line 624 "reflect.h2" +#line 627 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::impl::in s ) : declaration{ n_, s } -#line 629 "reflect.h2" +#line 632 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_alias)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } @@ -3712,35 +3740,35 @@ namespace_declaration::namespace_declaration(namespace_declaration&& that) noexc alias_declaration::alias_declaration(alias_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 636 "reflect.h2" +#line 639 "reflect.h2" //----------------------------------------------------------------------- // Parameter declarations // -#line 643 "reflect.h2" +#line 646 "reflect.h2" parameter_declaration::parameter_declaration( parameter_declaration_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 648 "reflect.h2" +#line 651 "reflect.h2" { } -#line 652 "reflect.h2" +#line 655 "reflect.h2" [[nodiscard]] auto parameter_declaration::get_declaration() const& -> object_declaration { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).declaration), (*this) }; } -#line 653 "reflect.h2" +#line 656 "reflect.h2" [[nodiscard]] auto parameter_declaration::get_passing_style() const& -> passing_style { return (*cpp2::impl::assert_not_null(n)).pass; } -#line 655 "reflect.h2" +#line 658 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_implicit() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::implicit; } -#line 656 "reflect.h2" +#line 659 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_virtual() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::virtual_; } -#line 657 "reflect.h2" +#line 660 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_override() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::override_; } -#line 658 "reflect.h2" +#line 661 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_final() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::final_; } parameter_declaration::parameter_declaration(parameter_declaration const& that) @@ -3748,7 +3776,7 @@ alias_declaration::alias_declaration(alias_declaration&& that) noexcept parameter_declaration::parameter_declaration(parameter_declaration&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 662 "reflect.h2" +#line 665 "reflect.h2" //----------------------------------------------------------------------- // // Expressions @@ -3760,45 +3788,45 @@ parameter_declaration::parameter_declaration(parameter_declaration&& that) noexc // Binary expressions // -#line 689 "reflect.h2" +#line 692 "reflect.h2" template binary_expression::binary_expression( binary_expression_node* n_, cpp2::impl::in s ) : reflection_base>{ n_, s } -#line 694 "reflect.h2" +#line 697 "reflect.h2" { } -#line 698 "reflect.h2" +#line 701 "reflect.h2" template [[nodiscard]] auto binary_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 699 "reflect.h2" +#line 702 "reflect.h2" template [[nodiscard]] auto binary_expression::lhs_is_id_expression() const& -> bool { return CPP2_UFCS(lhs_is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 700 "reflect.h2" +#line 703 "reflect.h2" template [[nodiscard]] auto binary_expression::is_standalone_expression() const& -> bool { return CPP2_UFCS(is_standalone_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 701 "reflect.h2" +#line 704 "reflect.h2" template [[nodiscard]] auto binary_expression::terms_size() const& -> int { return CPP2_UFCS(terms_size)((*cpp2::impl::assert_not_null((*this).n))); } -#line 702 "reflect.h2" +#line 705 "reflect.h2" template [[nodiscard]] auto binary_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null((*this).n))); } -#line 703 "reflect.h2" +#line 706 "reflect.h2" template [[nodiscard]] auto binary_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 704 "reflect.h2" +#line 707 "reflect.h2" template [[nodiscard]] auto binary_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 705 "reflect.h2" +#line 708 "reflect.h2" template [[nodiscard]] auto binary_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null((*this).n))); } -#line 706 "reflect.h2" +#line 709 "reflect.h2" template [[nodiscard]] auto binary_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null((*this).n))); } -#line 712 "reflect.h2" +#line 715 "reflect.h2" template template binary_expression::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , term{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 714 "reflect.h2" +#line 717 "reflect.h2" template template [[nodiscard]] auto binary_expression::term_t::get_op() const& -> std::string { return op; } -#line 715 "reflect.h2" +#line 718 "reflect.h2" template template [[nodiscard]] auto binary_expression::term_t::get_term() const& -> T { return term; } template template binary_expression::term_t::term_t(term_t const& that) @@ -3816,7 +3844,7 @@ template template auto binary_expressi op = std::move(that).op; term = std::move(that).term; return *this;} -#line 718 "reflect.h2" +#line 721 "reflect.h2" template [[nodiscard]] auto binary_expression::get_terms() const& -> auto{ if constexpr (std::is_same_v) { std::vector> ret {}; @@ -3892,25 +3920,25 @@ template template auto binary_expressi } } -#line 793 "reflect.h2" +#line 796 "reflect.h2" template [[nodiscard]] auto binary_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 794 "reflect.h2" +#line 797 "reflect.h2" template [[nodiscard]] auto binary_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null((*this).n))))); } // Get the postfix-expression, if that's the entire expression (not actually binary) -#line 797 "reflect.h2" +#line 800 "reflect.h2" template [[nodiscard]] auto binary_expression::get_if_only_a_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_if_only_a_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } // Get left-hand postfix-expression -#line 799 "reflect.h2" +#line 802 "reflect.h2" template [[nodiscard]] auto binary_expression::get_lhs_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } // Get first right-hand postfix-expression, if there is one -#line 801 "reflect.h2" +#line 804 "reflect.h2" template [[nodiscard]] auto binary_expression::get_second_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_second_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 803 "reflect.h2" +#line 806 "reflect.h2" template [[nodiscard]] auto binary_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null((*this).n))); } -#line 805 "reflect.h2" +#line 808 "reflect.h2" template [[nodiscard]] auto binary_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } template binary_expression::binary_expression(binary_expression const& that) @@ -3918,29 +3946,29 @@ template template auto binary_expressi template binary_expression::binary_expression(binary_expression&& that) noexcept : reflection_base>{ static_cast>&&>(that) }{} -#line 809 "reflect.h2" +#line 812 "reflect.h2" //----------------------------------------------------------------------- // Expression list // -#line 816 "reflect.h2" +#line 819 "reflect.h2" expression_list::expression_list( expression_list_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 821 "reflect.h2" +#line 824 "reflect.h2" { } -#line 825 "reflect.h2" +#line 828 "reflect.h2" [[nodiscard]] auto expression_list::is_empty() const& -> bool { return CPP2_UFCS(is_empty)((*cpp2::impl::assert_not_null(n))); } -#line 826 "reflect.h2" +#line 829 "reflect.h2" [[nodiscard]] auto expression_list::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 828 "reflect.h2" +#line 831 "reflect.h2" [[nodiscard]] auto expression_list::get_expressions() const& -> std::vector { @@ -3951,7 +3979,7 @@ template binary_expression::binary_expre return ret; } -#line 838 "reflect.h2" +#line 841 "reflect.h2" [[nodiscard]] auto expression_list::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression_list::expression_list(expression_list const& that) @@ -3959,24 +3987,24 @@ template binary_expression::binary_expre expression_list::expression_list(expression_list&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 842 "reflect.h2" +#line 845 "reflect.h2" //----------------------------------------------------------------------- // Prefix expressions // -#line 849 "reflect.h2" +#line 852 "reflect.h2" prefix_expression::prefix_expression( prefix_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 854 "reflect.h2" +#line 857 "reflect.h2" { } -#line 858 "reflect.h2" +#line 861 "reflect.h2" [[nodiscard]] auto prefix_expression::get_ops() const& -> std::vector{ std::vector ret {}; for ( auto const& op : (*cpp2::impl::assert_not_null(n)).ops ) { @@ -3985,32 +4013,32 @@ expression_list::expression_list(expression_list&& that) noexcept return ret; } -#line 866 "reflect.h2" +#line 869 "reflect.h2" [[nodiscard]] auto prefix_expression::get_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null((*this).n)).expr), (*this) }; } -#line 868 "reflect.h2" +#line 871 "reflect.h2" [[nodiscard]] auto prefix_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 869 "reflect.h2" +#line 872 "reflect.h2" [[nodiscard]] auto prefix_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 870 "reflect.h2" +#line 873 "reflect.h2" [[nodiscard]] auto prefix_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 871 "reflect.h2" +#line 874 "reflect.h2" [[nodiscard]] auto prefix_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 872 "reflect.h2" +#line 875 "reflect.h2" [[nodiscard]] auto prefix_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 873 "reflect.h2" +#line 876 "reflect.h2" [[nodiscard]] auto prefix_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 874 "reflect.h2" +#line 877 "reflect.h2" [[nodiscard]] auto prefix_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null(n))); } -#line 876 "reflect.h2" +#line 879 "reflect.h2" [[nodiscard]] auto prefix_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 877 "reflect.h2" +#line 880 "reflect.h2" [[nodiscard]] auto prefix_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 878 "reflect.h2" +#line 881 "reflect.h2" [[nodiscard]] auto prefix_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 880 "reflect.h2" +#line 883 "reflect.h2" [[nodiscard]] auto prefix_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } prefix_expression::~prefix_expression() noexcept{} @@ -4019,32 +4047,32 @@ prefix_expression::prefix_expression(prefix_expression const& that) prefix_expression::prefix_expression(prefix_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 884 "reflect.h2" +#line 887 "reflect.h2" //----------------------------------------------------------------------- // Postfix expressions // -#line 891 "reflect.h2" +#line 894 "reflect.h2" postfix_expression::postfix_expression( postfix_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 896 "reflect.h2" +#line 899 "reflect.h2" { } -#line 900 "reflect.h2" +#line 903 "reflect.h2" [[nodiscard]] auto postfix_expression::get_primary_expression() const& -> primary_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null((*this).n)).expr), (*this) }; } -#line 906 "reflect.h2" +#line 909 "reflect.h2" postfix_expression::term_t::term_t(auto&& term, auto&& cs) : term_{ CPP2_FORWARD(term) } , cs_{ CPP2_FORWARD(cs) }{} -#line 908 "reflect.h2" +#line 911 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_op() const& -> std::string_view { return CPP2_UFCS(as_string_view)((*cpp2::impl::assert_not_null((*cpp2::impl::assert_not_null(term_)).op))); } // If op is More is contained in the Notes @@ -4053,18 +4081,18 @@ prefix_expression::prefix_expression(prefix_expression&& that) noexcept // [ ( expression_list subscript or function call // ... expression fold expression -#line 916 "reflect.h2" +#line 919 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_id_expression() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).id_expr) != nullptr; } -#line 917 "reflect.h2" +#line 920 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_expression_list() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).expr_list) != nullptr; } -#line 918 "reflect.h2" +#line 921 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_expression() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).last_expr) != nullptr; } -#line 920 "reflect.h2" +#line 923 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_id_expression() const& -> id_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).id_expr), *cpp2::impl::assert_not_null(cs_) }; } -#line 921 "reflect.h2" +#line 924 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_expression_list() const& -> expression_list { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).expr_list), *cpp2::impl::assert_not_null(cs_) }; } -#line 922 "reflect.h2" +#line 925 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_expression() const& -> expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).last_expr), *cpp2::impl::assert_not_null(cs_) }; } postfix_expression::term_t::term_t(term_t const& that) @@ -4074,46 +4102,46 @@ postfix_expression::term_t::term_t(term_t&& that) noexcept : term_{ std::move(that).term_ } , cs_{ std::move(that).cs_ }{} -#line 925 "reflect.h2" +#line 928 "reflect.h2" [[nodiscard]] auto postfix_expression::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ops ) {static_cast(CPP2_UFCS(emplace_back)(ret, &t, &(*this))); } return ret; } -#line 931 "reflect.h2" +#line 934 "reflect.h2" [[nodiscard]] auto postfix_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 932 "reflect.h2" +#line 935 "reflect.h2" [[nodiscard]] auto postfix_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 933 "reflect.h2" +#line 936 "reflect.h2" [[nodiscard]] auto postfix_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 934 "reflect.h2" +#line 937 "reflect.h2" [[nodiscard]] auto postfix_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 935 "reflect.h2" +#line 938 "reflect.h2" [[nodiscard]] auto postfix_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 936 "reflect.h2" +#line 939 "reflect.h2" [[nodiscard]] auto postfix_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 938 "reflect.h2" +#line 941 "reflect.h2" [[nodiscard]] auto postfix_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 939 "reflect.h2" +#line 942 "reflect.h2" [[nodiscard]] auto postfix_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 940 "reflect.h2" +#line 943 "reflect.h2" [[nodiscard]] auto postfix_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 942 "reflect.h2" +#line 945 "reflect.h2" [[nodiscard]] auto postfix_expression::get_first_token_ignoring_this() const& -> std::string_view{ auto ptok {CPP2_UFCS(get_first_token_ignoring_this)((*cpp2::impl::assert_not_null(n)))}; if (ptok) {return *cpp2::impl::assert_not_null(cpp2::move(ptok)); } return ""; } -#line 948 "reflect.h2" +#line 951 "reflect.h2" [[nodiscard]] auto postfix_expression::starts_with_function_call_with_num_parameters(cpp2::impl::in num) const& -> bool { return CPP2_UFCS(starts_with_function_call_with_n_parameters)((*cpp2::impl::assert_not_null(n)), num); } -#line 949 "reflect.h2" +#line 952 "reflect.h2" [[nodiscard]] auto postfix_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null(n))); } -#line 951 "reflect.h2" +#line 954 "reflect.h2" [[nodiscard]] auto postfix_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } postfix_expression::postfix_expression(postfix_expression const& that) @@ -4121,34 +4149,34 @@ postfix_expression::term_t::term_t(term_t&& that) noexcept postfix_expression::postfix_expression(postfix_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 955 "reflect.h2" +#line 958 "reflect.h2" //----------------------------------------------------------------------- // Template arguments // -#line 962 "reflect.h2" +#line 965 "reflect.h2" template_arg::template_arg( template_argument* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 967 "reflect.h2" +#line 970 "reflect.h2" { } -#line 971 "reflect.h2" +#line 974 "reflect.h2" [[nodiscard]] auto template_arg::is_expression() const& -> bool { return CPP2_UFCS(is_expression)((*cpp2::impl::assert_not_null(n))); } -#line 972 "reflect.h2" +#line 975 "reflect.h2" [[nodiscard]] auto template_arg::is_type_id() const& -> bool { return CPP2_UFCS(is_type_id)((*cpp2::impl::assert_not_null(n))); } -#line 974 "reflect.h2" +#line 977 "reflect.h2" [[nodiscard]] auto template_arg::as_expression() const& -> expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 975 "reflect.h2" +#line 978 "reflect.h2" [[nodiscard]] auto template_arg::as_type_id() const& -> type_id { return { CPP2_UFCS(get_type_id)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 977 "reflect.h2" +#line 980 "reflect.h2" [[nodiscard]] auto template_arg::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } template_arg::template_arg(template_arg const& that) @@ -4156,27 +4184,27 @@ postfix_expression::postfix_expression(postfix_expression&& that) noexcept template_arg::template_arg(template_arg&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 981 "reflect.h2" +#line 984 "reflect.h2" //----------------------------------------------------------------------- // Unqualified IDs // -#line 988 "reflect.h2" +#line 991 "reflect.h2" unqualified_id::unqualified_id( unqualified_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 993 "reflect.h2" +#line 996 "reflect.h2" { } -#line 997 "reflect.h2" +#line 1000 "reflect.h2" [[nodiscard]] auto unqualified_id::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 999 "reflect.h2" +#line 1002 "reflect.h2" [[nodiscard]] auto unqualified_id::get_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } //get_template_args: (this) -> std::vector = { @@ -4185,10 +4213,10 @@ template_arg::template_arg(template_arg&& that) noexcept // return ret; //} -#line 1007 "reflect.h2" +#line 1010 "reflect.h2" [[nodiscard]] auto unqualified_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1009 "reflect.h2" +#line 1012 "reflect.h2" [[nodiscard]] auto unqualified_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } unqualified_id::unqualified_id(unqualified_id const& that) @@ -4196,31 +4224,31 @@ template_arg::template_arg(template_arg&& that) noexcept unqualified_id::unqualified_id(unqualified_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1013 "reflect.h2" +#line 1016 "reflect.h2" //----------------------------------------------------------------------- // Qualified IDs // -#line 1020 "reflect.h2" +#line 1023 "reflect.h2" qualified_id::qualified_id( qualified_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1025 "reflect.h2" +#line 1028 "reflect.h2" { } -#line 1033 "reflect.h2" +#line 1036 "reflect.h2" qualified_id::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , unqualified{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 1035 "reflect.h2" +#line 1038 "reflect.h2" [[nodiscard]] auto qualified_id::term_t::get_op() const& -> std::string { return op; } -#line 1036 "reflect.h2" +#line 1039 "reflect.h2" [[nodiscard]] auto qualified_id::term_t::get_unqualified() const& -> unqualified_id { return unqualified; } qualified_id::term_t::term_t(term_t const& that) @@ -4230,7 +4258,7 @@ qualified_id::term_t::term_t(term_t&& that) noexcept : op{ std::move(that).op } , unqualified{ std::move(that).unqualified }{} -#line 1039 "reflect.h2" +#line 1042 "reflect.h2" [[nodiscard]] auto qualified_id::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ids ) {static_cast(CPP2_UFCS(emplace_back)(ret, *cpp2::impl::assert_not_null(t.scope_op), CPP2_UFCS(get)(t.id), (*this))); } @@ -4243,10 +4271,10 @@ qualified_id::term_t::term_t(term_t&& that) noexcept // return ret; //} -#line 1051 "reflect.h2" +#line 1054 "reflect.h2" [[nodiscard]] auto qualified_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1053 "reflect.h2" +#line 1056 "reflect.h2" [[nodiscard]] auto qualified_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } qualified_id::qualified_id(qualified_id const& that) @@ -4254,19 +4282,19 @@ qualified_id::term_t::term_t(term_t&& that) noexcept qualified_id::qualified_id(qualified_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1057 "reflect.h2" +#line 1060 "reflect.h2" //----------------------------------------------------------------------- // Type IDs // -#line 1064 "reflect.h2" +#line 1067 "reflect.h2" type_id::type_id( type_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1069 "reflect.h2" +#line 1072 "reflect.h2" { } @@ -4277,37 +4305,37 @@ qualified_id::qualified_id(qualified_id&& that) noexcept // return ret; //} -#line 1079 "reflect.h2" +#line 1082 "reflect.h2" [[nodiscard]] auto type_id::is_postfix_expression() const& -> bool { return CPP2_UFCS(is_postfix_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1080 "reflect.h2" +#line 1083 "reflect.h2" [[nodiscard]] auto type_id::is_qualified_id() const& -> bool { return CPP2_UFCS(is_qualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1081 "reflect.h2" +#line 1084 "reflect.h2" [[nodiscard]] auto type_id::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1082 "reflect.h2" +#line 1085 "reflect.h2" [[nodiscard]] auto type_id::is_function_typeid() const& -> bool { return CPP2_UFCS(is_function_typeid)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1083 "reflect.h2" +#line 1086 "reflect.h2" [[nodiscard]] auto type_id::is_keyword() const& -> bool { return CPP2_UFCS(is_keyword)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1084 "reflect.h2" +#line 1087 "reflect.h2" [[nodiscard]] auto type_id::is_wildcard() const& -> bool { return CPP2_UFCS(is_wildcard)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1085 "reflect.h2" +#line 1088 "reflect.h2" [[nodiscard]] auto type_id::is_pointer_qualified() const& -> bool { return CPP2_UFCS(is_pointer_qualified)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1086 "reflect.h2" +#line 1089 "reflect.h2" [[nodiscard]] auto type_id::is_concept() const& -> bool { return CPP2_UFCS(is_concept)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1088 "reflect.h2" +#line 1091 "reflect.h2" [[nodiscard]] auto type_id::as_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_postfix_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1089 "reflect.h2" +#line 1092 "reflect.h2" [[nodiscard]] auto type_id::as_qualified_id() const& -> qualified_id { return { CPP2_UFCS(get_qualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1090 "reflect.h2" +#line 1093 "reflect.h2" [[nodiscard]] auto type_id::as_unqualified_id() const& -> unqualified_id { return { CPP2_UFCS(get_unqualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } // TODO //as_function_typeid : (this) -> function_typeid = (n*.get_function_typeid(), this); -#line 1093 "reflect.h2" +#line 1096 "reflect.h2" [[nodiscard]] auto type_id::as_keyword() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_keyword)(*cpp2::impl::assert_not_null(n))))); } -#line 1094 "reflect.h2" +#line 1097 "reflect.h2" [[nodiscard]] auto type_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1096 "reflect.h2" +#line 1099 "reflect.h2" [[nodiscard]] auto type_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } type_id::type_id(type_id const& that) @@ -4315,19 +4343,19 @@ qualified_id::qualified_id(qualified_id&& that) noexcept type_id::type_id(type_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1100 "reflect.h2" +#line 1103 "reflect.h2" //----------------------------------------------------------------------- // Primary expressions // -#line 1107 "reflect.h2" +#line 1110 "reflect.h2" primary_expression::primary_expression( primary_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1112 "reflect.h2" +#line 1115 "reflect.h2" { } @@ -4338,31 +4366,31 @@ type_id::type_id(type_id&& that) noexcept // return ret; //} -#line 1122 "reflect.h2" +#line 1125 "reflect.h2" [[nodiscard]] auto primary_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1123 "reflect.h2" +#line 1126 "reflect.h2" [[nodiscard]] auto primary_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1124 "reflect.h2" +#line 1127 "reflect.h2" [[nodiscard]] auto primary_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1125 "reflect.h2" +#line 1128 "reflect.h2" [[nodiscard]] auto primary_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 1126 "reflect.h2" +#line 1129 "reflect.h2" [[nodiscard]] auto primary_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1127 "reflect.h2" +#line 1130 "reflect.h2" [[nodiscard]] auto primary_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 1128 "reflect.h2" +#line 1131 "reflect.h2" [[nodiscard]] auto primary_expression::is_declaration() const& -> bool { return CPP2_UFCS(is_declaration)((*cpp2::impl::assert_not_null(n))); } -#line 1130 "reflect.h2" +#line 1133 "reflect.h2" [[nodiscard]] auto primary_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1131 "reflect.h2" +#line 1134 "reflect.h2" [[nodiscard]] auto primary_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1132 "reflect.h2" +#line 1135 "reflect.h2" [[nodiscard]] auto primary_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1133 "reflect.h2" +#line 1136 "reflect.h2" [[nodiscard]] auto primary_expression::as_declaration() const& -> declaration { return { CPP2_UFCS(get_declaration)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1135 "reflect.h2" +#line 1138 "reflect.h2" [[nodiscard]] auto primary_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } primary_expression::primary_expression(primary_expression const& that) @@ -4370,19 +4398,19 @@ type_id::type_id(type_id&& that) noexcept primary_expression::primary_expression(primary_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1139 "reflect.h2" +#line 1142 "reflect.h2" //----------------------------------------------------------------------- // ID expression // -#line 1146 "reflect.h2" +#line 1149 "reflect.h2" id_expression::id_expression( id_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1151 "reflect.h2" +#line 1154 "reflect.h2" { } @@ -4393,25 +4421,25 @@ primary_expression::primary_expression(primary_expression&& that) noexcept // return ret; //} -#line 1161 "reflect.h2" +#line 1164 "reflect.h2" [[nodiscard]] auto id_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1162 "reflect.h2" +#line 1165 "reflect.h2" [[nodiscard]] auto id_expression::is_empty() const& -> bool { return CPP2_UFCS(is_empty)((*cpp2::impl::assert_not_null(n))); } -#line 1163 "reflect.h2" +#line 1166 "reflect.h2" [[nodiscard]] auto id_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1164 "reflect.h2" +#line 1167 "reflect.h2" [[nodiscard]] auto id_expression::is_qualified() const& -> bool { return CPP2_UFCS(is_qualified)((*cpp2::impl::assert_not_null(n))); } -#line 1165 "reflect.h2" +#line 1168 "reflect.h2" [[nodiscard]] auto id_expression::is_unqualified() const& -> bool { return CPP2_UFCS(is_unqualified)((*cpp2::impl::assert_not_null(n))); } -#line 1167 "reflect.h2" +#line 1170 "reflect.h2" [[nodiscard]] auto id_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1168 "reflect.h2" +#line 1171 "reflect.h2" [[nodiscard]] auto id_expression::as_qualified() const& -> qualified_id { return { CPP2_UFCS(get_qualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1169 "reflect.h2" +#line 1172 "reflect.h2" [[nodiscard]] auto id_expression::as_unqualified() const& -> unqualified_id { return { CPP2_UFCS(get_unqualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1171 "reflect.h2" +#line 1174 "reflect.h2" [[nodiscard]] auto id_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } id_expression::~id_expression() noexcept{} @@ -4420,71 +4448,71 @@ id_expression::id_expression(id_expression const& that) id_expression::id_expression(id_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1175 "reflect.h2" +#line 1178 "reflect.h2" //----------------------------------------------------------------------- // General expression // -#line 1182 "reflect.h2" +#line 1185 "reflect.h2" expression::expression( expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1187 "reflect.h2" +#line 1190 "reflect.h2" { } -#line 1191 "reflect.h2" +#line 1194 "reflect.h2" [[nodiscard]] auto expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1192 "reflect.h2" +#line 1195 "reflect.h2" [[nodiscard]] auto expression::is_standalone_expression() const& -> bool { return CPP2_UFCS(is_standalone_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1193 "reflect.h2" +#line 1196 "reflect.h2" [[nodiscard]] auto expression::subexpression_count() const& -> int { return CPP2_UFCS(subexpression_count)((*cpp2::impl::assert_not_null(n))); } -#line 1194 "reflect.h2" +#line 1197 "reflect.h2" [[nodiscard]] auto expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1195 "reflect.h2" +#line 1198 "reflect.h2" [[nodiscard]] auto expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1196 "reflect.h2" +#line 1199 "reflect.h2" [[nodiscard]] auto expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 1197 "reflect.h2" +#line 1200 "reflect.h2" [[nodiscard]] auto expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1198 "reflect.h2" +#line 1201 "reflect.h2" [[nodiscard]] auto expression::is_empty_expression_list() const& -> bool { return CPP2_UFCS(is_empty_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1199 "reflect.h2" +#line 1202 "reflect.h2" [[nodiscard]] auto expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 1200 "reflect.h2" +#line 1203 "reflect.h2" [[nodiscard]] auto expression::is_assignment_expression() const& -> bool { return CPP2_UFCS(is_assignment_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1202 "reflect.h2" +#line 1205 "reflect.h2" [[nodiscard]] auto expression::is_simple_assignment() const& -> bool{ auto ret {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)((*cpp2::impl::assert_not_null(n)))}; return ret.lhs && ret.rhs; } -#line 1207 "reflect.h2" +#line 1210 "reflect.h2" [[nodiscard]] auto expression::get_lhs_rhs_if_simple_assignment() const& -> get_lhs_rhs_if_simple_assignment_ret -#line 1212 "reflect.h2" +#line 1215 "reflect.h2" { cpp2::impl::deferred_init lhs; cpp2::impl::deferred_init rhs; -#line 1213 "reflect.h2" +#line 1216 "reflect.h2" auto ret {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)((*cpp2::impl::assert_not_null(n)))}; lhs.construct(ret.lhs, (*this)); rhs.construct(cpp2::move(ret).rhs, (*this)); return { std::move(lhs.value()), std::move(rhs.value()) }; } -#line 1218 "reflect.h2" +#line 1221 "reflect.h2" [[nodiscard]] auto expression::as_assignment_expression() const& -> assignment_expression { return { CPP2_UFCS(get_assignment_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1219 "reflect.h2" +#line 1222 "reflect.h2" [[nodiscard]] auto expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1220 "reflect.h2" +#line 1223 "reflect.h2" [[nodiscard]] auto expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1222 "reflect.h2" +#line 1225 "reflect.h2" [[nodiscard]] auto expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression::~expression() noexcept{} @@ -4493,31 +4521,31 @@ expression::expression(expression const& that) expression::expression(expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1226 "reflect.h2" +#line 1229 "reflect.h2" //----------------------------------------------------------------------- // is_as_expression // -#line 1233 "reflect.h2" +#line 1236 "reflect.h2" is_as_expression::is_as_expression( is_as_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1238 "reflect.h2" +#line 1241 "reflect.h2" { } -#line 1246 "reflect.h2" +#line 1249 "reflect.h2" is_as_expression::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , expr{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 1248 "reflect.h2" +#line 1251 "reflect.h2" [[nodiscard]] auto is_as_expression::term_t::get_op() const& -> std::string { return op; } -#line 1249 "reflect.h2" +#line 1252 "reflect.h2" [[nodiscard]] auto is_as_expression::term_t::get_expr() const& -> expression { return expr; } is_as_expression::term_t::term_t(term_t const& that) @@ -4527,42 +4555,42 @@ is_as_expression::term_t::term_t(term_t&& that) noexcept : op{ std::move(that).op } , expr{ std::move(that).expr }{} -#line 1252 "reflect.h2" +#line 1255 "reflect.h2" [[nodiscard]] auto is_as_expression::get_expression() const& -> prefix_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).expr), (*this) }; } -#line 1254 "reflect.h2" +#line 1257 "reflect.h2" [[nodiscard]] auto is_as_expression::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ops ) {static_cast(CPP2_UFCS(emplace_back)(ret, *cpp2::impl::assert_not_null(t.op), CPP2_UFCS(get)(t.expr), (*this))); } return ret; } -#line 1260 "reflect.h2" +#line 1263 "reflect.h2" [[nodiscard]] auto is_as_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1261 "reflect.h2" +#line 1264 "reflect.h2" [[nodiscard]] auto is_as_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1262 "reflect.h2" +#line 1265 "reflect.h2" [[nodiscard]] auto is_as_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1263 "reflect.h2" +#line 1266 "reflect.h2" [[nodiscard]] auto is_as_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1264 "reflect.h2" +#line 1267 "reflect.h2" [[nodiscard]] auto is_as_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1265 "reflect.h2" +#line 1268 "reflect.h2" [[nodiscard]] auto is_as_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1267 "reflect.h2" +#line 1270 "reflect.h2" [[nodiscard]] auto is_as_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1268 "reflect.h2" +#line 1271 "reflect.h2" [[nodiscard]] auto is_as_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1270 "reflect.h2" +#line 1273 "reflect.h2" [[nodiscard]] auto is_as_expression::get_identifier() const& -> std::string_view{ auto ptok {CPP2_UFCS(get_identifier)((*cpp2::impl::assert_not_null((*this).n)))}; if (ptok) {return *cpp2::impl::assert_not_null(cpp2::move(ptok)); } return ""; } -#line 1276 "reflect.h2" +#line 1279 "reflect.h2" [[nodiscard]] auto is_as_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } is_as_expression::~is_as_expression() noexcept{} @@ -4571,7 +4599,7 @@ is_as_expression::is_as_expression(is_as_expression const& that) is_as_expression::is_as_expression(is_as_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1280 "reflect.h2" +#line 1283 "reflect.h2" //----------------------------------------------------------------------- // // Statements @@ -4583,57 +4611,57 @@ is_as_expression::is_as_expression(is_as_expression&& that) noexcept // General statement // -#line 1294 "reflect.h2" +#line 1297 "reflect.h2" statement::statement( statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1299 "reflect.h2" +#line 1302 "reflect.h2" { } -#line 1303 "reflect.h2" +#line 1306 "reflect.h2" [[nodiscard]] auto statement::is_expression_statement() const& -> bool { return CPP2_UFCS(is_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1304 "reflect.h2" +#line 1307 "reflect.h2" [[nodiscard]] auto statement::is_compound_statement() const& -> bool { return CPP2_UFCS(is_compound)((*cpp2::impl::assert_not_null(n))); } -#line 1305 "reflect.h2" +#line 1308 "reflect.h2" [[nodiscard]] auto statement::is_selection_statement() const& -> bool { return CPP2_UFCS(is_selection)((*cpp2::impl::assert_not_null(n))); } -#line 1306 "reflect.h2" +#line 1309 "reflect.h2" [[nodiscard]] auto statement::is_declaration() const& -> bool { return CPP2_UFCS(is_declaration)((*cpp2::impl::assert_not_null(n))); } -#line 1307 "reflect.h2" +#line 1310 "reflect.h2" [[nodiscard]] auto statement::is_return_statement() const& -> bool { return CPP2_UFCS(is_return)((*cpp2::impl::assert_not_null(n))); } -#line 1308 "reflect.h2" +#line 1311 "reflect.h2" [[nodiscard]] auto statement::is_iteration_statement() const& -> bool { return CPP2_UFCS(is_iteration)((*cpp2::impl::assert_not_null(n))); } -#line 1309 "reflect.h2" +#line 1312 "reflect.h2" [[nodiscard]] auto statement::is_using_statement() const& -> bool { return CPP2_UFCS(is_using)((*cpp2::impl::assert_not_null(n))); } -#line 1310 "reflect.h2" +#line 1313 "reflect.h2" [[nodiscard]] auto statement::is_contract() const& -> bool { return CPP2_UFCS(is_contract)((*cpp2::impl::assert_not_null(n))); } -#line 1311 "reflect.h2" +#line 1314 "reflect.h2" [[nodiscard]] auto statement::is_inspect_expression() const& -> bool { return CPP2_UFCS(is_inspect)((*cpp2::impl::assert_not_null(n))); } -#line 1312 "reflect.h2" +#line 1315 "reflect.h2" [[nodiscard]] auto statement::is_jump_statement() const& -> bool { return CPP2_UFCS(is_jump)((*cpp2::impl::assert_not_null(n))); } -#line 1314 "reflect.h2" +#line 1317 "reflect.h2" [[nodiscard]] auto statement::as_expression_statement() const& -> expression_statement { return { CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1315 "reflect.h2" +#line 1318 "reflect.h2" [[nodiscard]] auto statement::as_compound_statement() const& -> compound_statement { return { CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1316 "reflect.h2" +#line 1319 "reflect.h2" [[nodiscard]] auto statement::as_selection_statement() const& -> selection_statement { return selection_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1317 "reflect.h2" +#line 1320 "reflect.h2" [[nodiscard]] auto statement::as_declaration() const& -> declaration { return declaration(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1318 "reflect.h2" +#line 1321 "reflect.h2" [[nodiscard]] auto statement::as_return_statement() const& -> return_statement { return return_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1319 "reflect.h2" +#line 1322 "reflect.h2" [[nodiscard]] auto statement::as_iteration_statement() const& -> iteration_statement { return iteration_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } //as_using_statement : (this) -> using_statement = using_statement (n*.get_if(), this); //as_contract : (this) -> contract = contract (n*.get_if(), this); //as_inspect_expression : (this) -> inspect_expression = inspect_expression (n*.get_if(), this); //as_jump_statement : (this) -> jump_statement = jump_statement (n*.get_if(), this); -#line 1325 "reflect.h2" +#line 1328 "reflect.h2" [[nodiscard]] auto statement::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } statement::~statement() noexcept{} @@ -4642,27 +4670,27 @@ statement::statement(statement const& that) statement::statement(statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1329 "reflect.h2" +#line 1332 "reflect.h2" //----------------------------------------------------------------------- // Expression statements // -#line 1336 "reflect.h2" +#line 1339 "reflect.h2" expression_statement::expression_statement( expression_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1341 "reflect.h2" +#line 1344 "reflect.h2" { } -#line 1345 "reflect.h2" +#line 1348 "reflect.h2" [[nodiscard]] auto expression_statement::get_expression() const& -> expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).expr), (*this) }; } -#line 1347 "reflect.h2" +#line 1350 "reflect.h2" [[nodiscard]] auto expression_statement::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression_statement::expression_statement(expression_statement const& that) @@ -4670,24 +4698,24 @@ statement::statement(statement&& that) noexcept expression_statement::expression_statement(expression_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1351 "reflect.h2" +#line 1354 "reflect.h2" //----------------------------------------------------------------------- // Compound statements // -#line 1358 "reflect.h2" +#line 1361 "reflect.h2" compound_statement::compound_statement( compound_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1363 "reflect.h2" +#line 1366 "reflect.h2" { } -#line 1367 "reflect.h2" +#line 1370 "reflect.h2" [[nodiscard]] auto compound_statement::get_statements() const& -> std::vector { @@ -4698,7 +4726,7 @@ expression_statement::expression_statement(expression_statement&& that) noexcept return ret; } -#line 1377 "reflect.h2" +#line 1380 "reflect.h2" auto compound_statement::add_statement(cpp2::impl::in source, cpp2::impl::in before_position) & -> void { auto stmt {parse_statement(source)}; @@ -4715,35 +4743,35 @@ expression_statement::expression_statement(expression_statement&& that) noexcept compound_statement::compound_statement(compound_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1390 "reflect.h2" +#line 1393 "reflect.h2" //----------------------------------------------------------------------- // Selection statements // -#line 1397 "reflect.h2" +#line 1400 "reflect.h2" selection_statement::selection_statement( selection_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1402 "reflect.h2" +#line 1405 "reflect.h2" { } -#line 1406 "reflect.h2" +#line 1409 "reflect.h2" [[nodiscard]] auto selection_statement::has_false_branch_in_source_code() const& -> bool { return CPP2_UFCS(has_false_branch_in_source_code)((*cpp2::impl::assert_not_null(n))); } -#line 1407 "reflect.h2" +#line 1410 "reflect.h2" [[nodiscard]] auto selection_statement::has_false_branch() const& -> bool { return CPP2_UFCS(has_false_branch)((*cpp2::impl::assert_not_null(n))); } -#line 1409 "reflect.h2" +#line 1412 "reflect.h2" [[nodiscard]] auto selection_statement::get_identifier() const& -> std::string_view { return CPP2_UFCS(as_string_view)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1410 "reflect.h2" +#line 1413 "reflect.h2" [[nodiscard]] auto selection_statement::get_expression() const& -> logical_or_expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1411 "reflect.h2" +#line 1414 "reflect.h2" [[nodiscard]] auto selection_statement::get_true_branch() const& -> compound_statement { return { CPP2_UFCS(get_true_branch)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1412 "reflect.h2" +#line 1415 "reflect.h2" [[nodiscard]] auto selection_statement::get_false_branch() const& -> compound_statement { return { CPP2_UFCS(get_false_branch)((*cpp2::impl::assert_not_null(n))), (*this) }; } selection_statement::selection_statement(selection_statement const& that) @@ -4751,27 +4779,27 @@ compound_statement::compound_statement(compound_statement&& that) noexcept selection_statement::selection_statement(selection_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1416 "reflect.h2" +#line 1419 "reflect.h2" //----------------------------------------------------------------------- // Return statements // -#line 1423 "reflect.h2" +#line 1426 "reflect.h2" return_statement::return_statement( return_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1428 "reflect.h2" +#line 1431 "reflect.h2" { } -#line 1432 "reflect.h2" +#line 1435 "reflect.h2" [[nodiscard]] auto return_statement::has_expression() const& -> bool { return CPP2_UFCS(has_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1434 "reflect.h2" +#line 1437 "reflect.h2" [[nodiscard]] auto return_statement::get_expression() const& -> expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } return_statement::return_statement(return_statement const& that) @@ -4779,45 +4807,45 @@ selection_statement::selection_statement(selection_statement&& that) noexcept return_statement::return_statement(return_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1438 "reflect.h2" +#line 1441 "reflect.h2" //----------------------------------------------------------------------- // Iteration statements - for, do, while // -#line 1445 "reflect.h2" +#line 1448 "reflect.h2" iteration_statement::iteration_statement( iteration_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1450 "reflect.h2" +#line 1453 "reflect.h2" { } -#line 1454 "reflect.h2" +#line 1457 "reflect.h2" [[nodiscard]] auto iteration_statement::is_do() const& -> bool { return CPP2_UFCS(is_do)((*cpp2::impl::assert_not_null(n))); } -#line 1455 "reflect.h2" +#line 1458 "reflect.h2" [[nodiscard]] auto iteration_statement::is_while() const& -> bool { return CPP2_UFCS(is_while)((*cpp2::impl::assert_not_null(n))); } -#line 1456 "reflect.h2" +#line 1459 "reflect.h2" [[nodiscard]] auto iteration_statement::is_for() const& -> bool { return CPP2_UFCS(is_for)((*cpp2::impl::assert_not_null(n))); } -#line 1457 "reflect.h2" +#line 1460 "reflect.h2" [[nodiscard]] auto iteration_statement::has_next() const& -> bool { return CPP2_UFCS(has_next)((*cpp2::impl::assert_not_null(n))); } -#line 1459 "reflect.h2" +#line 1462 "reflect.h2" [[nodiscard]] auto iteration_statement::get_label() const& -> std::string { return CPP2_UFCS(to_string)(CPP2_UFCS(get_label)((*cpp2::impl::assert_not_null(n)))); } -#line 1460 "reflect.h2" +#line 1463 "reflect.h2" [[nodiscard]] auto iteration_statement::get_next_expression() const& -> assignment_expression { return { CPP2_UFCS(get_next_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1461 "reflect.h2" +#line 1464 "reflect.h2" [[nodiscard]] auto iteration_statement::get_do_while_condition() const& -> logical_or_expression { return { CPP2_UFCS(get_do_while_condition)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1462 "reflect.h2" +#line 1465 "reflect.h2" [[nodiscard]] auto iteration_statement::get_do_while_body() const& -> compound_statement { return { CPP2_UFCS(get_do_while_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1463 "reflect.h2" +#line 1466 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_range() const& -> expression { return { CPP2_UFCS(get_for_range)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1464 "reflect.h2" +#line 1467 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_parameter() const& -> parameter_declaration { return { CPP2_UFCS(get_for_parameter)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1465 "reflect.h2" +#line 1468 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_body() const& -> statement { return { CPP2_UFCS(get_for_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } iteration_statement::iteration_statement(iteration_statement const& that) @@ -4825,7 +4853,7 @@ return_statement::return_statement(return_statement&& that) noexcept iteration_statement::iteration_statement(iteration_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1469 "reflect.h2" +#line 1472 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -4838,13 +4866,13 @@ iteration_statement::iteration_statement(iteration_statement&& that) noexcept // Some common metafunction helpers (metafunctions are just functions, // so they can be factored as usual) // -#line 1481 "reflect.h2" +#line 1484 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 1487 "reflect.h2" +#line 1490 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -4859,7 +4887,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void // a public default constructor, a public virtual destructor, and // protected copy/move operations // -#line 1501 "reflect.h2" +#line 1504 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -4891,7 +4919,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 1533 "reflect.h2" +#line 1536 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -4908,7 +4936,7 @@ auto interface(meta::type_declaration& t) -> void // // Unlike an interface, it can have nonpublic and nonvirtual functions. // -#line 1549 "reflect.h2" +#line 1552 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -4933,7 +4961,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 1574 "reflect.h2" +#line 1577 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -4954,7 +4982,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // -#line 1594 "reflect.h2" +#line 1597 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::impl::in ordering// must be "strong_ordering" etc. @@ -4984,7 +5012,7 @@ auto ordered_impl( // // Note: the ordering that should be encouraged as default gets the nice name // -#line 1623 "reflect.h2" +#line 1626 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); @@ -4993,7 +5021,7 @@ auto ordered(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // -#line 1631 "reflect.h2" +#line 1634 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); @@ -5002,13 +5030,13 @@ auto weakly_ordered(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // -#line 1639 "reflect.h2" +#line 1642 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 1645 "reflect.h2" +#line 1648 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -5025,7 +5053,7 @@ auto partially_ordered(meta::type_declaration& t) -> void // // A type with (copy and move) x (construction and assignment) // -#line 1661 "reflect.h2" +#line 1664 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -5053,12 +5081,12 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 1689 "reflect.h2" +#line 1692 "reflect.h2" // copy_constructible // // A type with (copy and move) construction // -#line 1693 "reflect.h2" +#line 1696 "reflect.h2" auto copy_constructible(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move constructors, @@ -5084,14 +5112,14 @@ auto copy_constructible(meta::type_declaration& t) -> void }} } -#line 1719 "reflect.h2" +#line 1722 "reflect.h2" //----------------------------------------------------------------------- // // hashable // // A memberwise hashable type // -#line 1725 "reflect.h2" +#line 1728 "reflect.h2" auto hashable(meta::type_declaration& t) -> void { CPP2_UFCS(require)(t, !(CPP2_UFCS(empty)(CPP2_UFCS(get_member_objects)(t))), @@ -5117,7 +5145,7 @@ auto hashable(meta::type_declaration& t) -> void CPP2_UFCS(add_member)(t, cpp2::move(hash) + "\n return ret;\n }"); } -#line 1751 "reflect.h2" +#line 1754 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -5125,7 +5153,7 @@ auto hashable(meta::type_declaration& t) -> void // A regular type: copyable, plus has public default construction // and no protected or virtual functions // -#line 1758 "reflect.h2" +#line 1761 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -5154,28 +5182,28 @@ auto basic_value(meta::type_declaration& t) -> void // // Note: the ordering that should be encouraged as default gets the nice name // -#line 1786 "reflect.h2" +#line 1789 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1792 "reflect.h2" +#line 1795 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(weakly_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1798 "reflect.h2" +#line 1801 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(partially_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1805 "reflect.h2" +#line 1808 "reflect.h2" //----------------------------------------------------------------------- // // C.20: If you can avoid defining default operations, do @@ -5198,7 +5226,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void // // a type without declared copy/move/destructor functions // -#line 1827 "reflect.h2" +#line 1830 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void { for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) @@ -5241,7 +5269,7 @@ auto cpp1_rule_of_zero(meta::type_declaration& t) -> void // parameters instead of concrete forwarding parameters (mainly used // for cppfront internal use, so cppfront builds under GCC 10) // -#line 1869 "reflect.h2" +#line 1872 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { std::string ctor_params {}; @@ -5298,7 +5326,7 @@ value_member_info::value_member_info(auto const& name_, auto const& type_, auto , type{ type_ } , value{ value_ }{} -#line 1921 "reflect.h2" +#line 1924 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -5317,7 +5345,7 @@ value_member_info::value_member_info(auto const& name_, auto const& type_, auto // a type together with named constants that are its possible values // -#line 1944 "reflect.h2" +#line 1947 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -5342,7 +5370,7 @@ auto basic_enum( { std::string value{"-1"}; -#line 1967 "reflect.h2" +#line 1970 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -5384,7 +5412,7 @@ std::string value{"-1"}; } } -#line 2007 "reflect.h2" +#line 2010 "reflect.h2" if ((CPP2_UFCS(empty)(enumerators))) { CPP2_UFCS(error)(t, "an enumeration must contain at least one enumerator value"); return ; @@ -5435,7 +5463,7 @@ std::string value{"-1"}; } } -#line 2058 "reflect.h2" +#line 2061 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents // // Note that most values and functions are declared as '==' compile-time values, i.e. Cpp1 'constexpr' @@ -5485,7 +5513,7 @@ std::string to_string_impl{" to_string_impl: (this, prefix: std::string_view" // Provide 'to_string' and 'to_code' functions to print enumerator // name(s) as human-readable strings or as code expressions -#line 2105 "reflect.h2" +#line 2108 "reflect.h2" { if (bitwise) { to_string_impl += ", separator: std::string_view ) -> std::string = { \n" @@ -5526,7 +5554,7 @@ std::string to_string_impl{" to_string_impl: (this, prefix: std::string_view" } } -#line 2144 "reflect.h2" +#line 2147 "reflect.h2" if (bitwise) { CPP2_UFCS(add_member)(t, " to_string: (this) -> std::string = to_string_impl( \"\", \", \" );"); CPP2_UFCS(add_member)(t, " to_code : (this) -> std::string = to_string_impl( \"" + cpp2::to_string(CPP2_UFCS(name)(t)) + "::\", \" | \" );"); @@ -5540,7 +5568,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ // Provide a 'from_string' function to parse strings into enumerators -#line 2155 "reflect.h2" +#line 2158 "reflect.h2" { std::string_view prefix {""}; std::string_view combine_op {"return"}; @@ -5562,7 +5590,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ { std::string_view else_{""}; -#line 2175 "reflect.h2" +#line 2178 "reflect.h2" for ( auto const& e : cpp2::move(enumerators) ) { from_string += " " + cpp2::to_string(else_) + "if \"" + cpp2::to_string(e.name) + "\" == x { " + cpp2::to_string(combine_op) + " " + cpp2::to_string(CPP2_UFCS(name)(t)) + "::" + cpp2::to_string(e.name) + "; }\n"; @@ -5570,7 +5598,7 @@ std::string_view else_{""}; } } -#line 2181 "reflect.h2" +#line 2184 "reflect.h2" if (bitwise) { from_string += " else { break outer; }\n" " }\n" @@ -5586,11 +5614,11 @@ std::string_view else_{""}; } } -#line 2195 "reflect.h2" +#line 2198 "reflect.h2" CPP2_UFCS(add_member)(t, " from_code: (s: std::string_view) -> " + cpp2::to_string(CPP2_UFCS(name)(t)) + " = { str: std::string = s; return from_string( cpp2::string_util::replace_all(str, \"" + cpp2::to_string(CPP2_UFCS(name)(t)) + "::\", \"\" ) ); }"); } -#line 2199 "reflect.h2" +#line 2202 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -5600,7 +5628,7 @@ std::string_view else_{""}; // // -- P0707R4, section 3 // -#line 2208 "reflect.h2" +#line 2211 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -5617,7 +5645,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 2225 "reflect.h2" +#line 2228 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -5628,7 +5656,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void // // -- P0707R4, section 3 // -#line 2235 "reflect.h2" +#line 2238 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -5650,7 +5678,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 2257 "reflect.h2" +#line 2260 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -5675,7 +5703,7 @@ auto flag_enum(meta::type_declaration& t) -> void // a type that contains exactly one of a fixed set of values at a time // -#line 2281 "reflect.h2" +#line 2284 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -5684,7 +5712,7 @@ auto value{0}; // 1. Gather: All the user-written members, and find/compute the max size -#line 2288 "reflect.h2" +#line 2291 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -5714,7 +5742,7 @@ auto value{0}; } while (false); ++value; } } -#line 2316 "reflect.h2" +#line 2319 "reflect.h2" std::string discriminator_type {}; if (cpp2::impl::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -5729,7 +5757,7 @@ auto value{0}; discriminator_type = "i64"; }}} -#line 2331 "reflect.h2" +#line 2334 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -5738,7 +5766,7 @@ std::string storage{" _storage: cpp2::aligned_storage t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 2438 "reflect.h2" +#line 2441 "reflect.h2" //----------------------------------------------------------------------- // // noisy - make each function print its name and signature, // so the programmer can see what's called // -#line 2443 "reflect.h2" +#line 2446 "reflect.h2" auto noisy(cpp2::impl::in t) -> void { for ( @@ -5875,12 +5903,12 @@ auto noisy(cpp2::impl::in t) -> void } } -#line 2460 "reflect.h2" +#line 2463 "reflect.h2" //----------------------------------------------------------------------- // // For reflection test cases // -#line 2464 "reflect.h2" +#line 2467 "reflect.h2" auto sample_print(cpp2::impl::in s, cpp2::impl::in indent) -> void { std::cout @@ -5889,12 +5917,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in << "\n"; } -#line 2474 "reflect.h2" +#line 2477 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in decl) -> void{ traverse(decl); } -#line 2478 "reflect.h2" +#line 2481 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in decl) -> void { if (CPP2_UFCS(is_function)(decl)) { @@ -5914,12 +5942,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // ... } -#line 2498 "reflect.h2" +#line 2501 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in f) -> void{ traverse(f); } -#line 2502 "reflect.h2" +#line 2505 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in f) -> void { auto parameters {CPP2_UFCS(get_parameters)(f)}; @@ -5940,12 +5968,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2523 "reflect.h2" +#line 2526 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in o) -> void{ traverse(o); } -#line 2527 "reflect.h2" +#line 2530 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in o) -> void { if (CPP2_UFCS(has_initializer)(o)) { @@ -5953,12 +5981,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2535 "reflect.h2" +#line 2538 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ traverse(t); } -#line 2539 "reflect.h2" +#line 2542 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in t) -> void { for ( auto const& m : CPP2_UFCS(get_members)(t) ) { @@ -5966,23 +5994,23 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2547 "reflect.h2" +#line 2550 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ traverse(t); } -#line 2551 "reflect.h2" +#line 2554 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in t) -> void { pre_traverse(CPP2_UFCS(get_declaration)(t)); } -#line 2556 "reflect.h2" +#line 2559 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2560 "reflect.h2" +#line 2563 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6017,12 +6045,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // jump } -#line 2595 "reflect.h2" +#line 2598 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2599 "reflect.h2" +#line 2602 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6032,12 +6060,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2609 "reflect.h2" +#line 2612 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2613 "reflect.h2" +#line 2616 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(has_expression)(stmt)) { @@ -6045,12 +6073,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2621 "reflect.h2" +#line 2624 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2625 "reflect.h2" +#line 2628 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6069,12 +6097,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2644 "reflect.h2" +#line 2647 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2648 "reflect.h2" +#line 2651 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { pre_traverse(CPP2_UFCS(get_expression)(stmt)); @@ -6085,14 +6113,14 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2659 "reflect.h2" +#line 2662 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in expr) -> void { // Nothing to select here. traverse(expr); } -#line 2665 "reflect.h2" +#line 2668 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in expr) -> void { // An expression has other shortcuts to query deeper properties, @@ -6106,7 +6134,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in pre_traverse(CPP2_UFCS(as_assignment_expression)(expr)); } -#line 2679 "reflect.h2" +#line 2682 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6124,7 +6152,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2696 "reflect.h2" +#line 2699 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6136,7 +6164,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2707 "reflect.h2" +#line 2710 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6154,7 +6182,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2724 "reflect.h2" +#line 2727 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6166,7 +6194,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2736 "reflect.h2" +#line 2739 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6184,7 +6212,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2753 "reflect.h2" +#line 2756 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6196,7 +6224,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2764 "reflect.h2" +#line 2767 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6214,7 +6242,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2781 "reflect.h2" +#line 2784 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6226,7 +6254,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2792 "reflect.h2" +#line 2795 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6244,7 +6272,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2809 "reflect.h2" +#line 2812 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6256,7 +6284,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2821 "reflect.h2" +#line 2824 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6274,7 +6302,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2838 "reflect.h2" +#line 2841 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6286,7 +6314,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2850 "reflect.h2" +#line 2853 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6304,7 +6332,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2867 "reflect.h2" +#line 2870 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6316,7 +6344,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2878 "reflect.h2" +#line 2881 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6334,7 +6362,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2895 "reflect.h2" +#line 2898 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6346,7 +6374,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2906 "reflect.h2" +#line 2909 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6364,7 +6392,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2923 "reflect.h2" +#line 2926 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6376,7 +6404,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2934 "reflect.h2" +#line 2937 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6394,7 +6422,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2951 "reflect.h2" +#line 2954 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6406,7 +6434,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2962 "reflect.h2" +#line 2965 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6424,7 +6452,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2979 "reflect.h2" +#line 2982 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6436,7 +6464,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2991 "reflect.h2" +#line 2994 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6454,7 +6482,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3008 "reflect.h2" +#line 3011 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6466,7 +6494,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3019 "reflect.h2" +#line 3022 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6483,7 +6511,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3035 "reflect.h2" +#line 3038 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6495,7 +6523,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3046 "reflect.h2" +#line 3049 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in exprs) -> void { for ( auto const& expr : CPP2_UFCS(get_expressions)(exprs) ) { @@ -6503,7 +6531,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3053 "reflect.h2" +#line 3056 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -6520,13 +6548,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3069 "reflect.h2" +#line 3072 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in prefix) -> void { pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); } -#line 3074 "reflect.h2" +#line 3077 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6543,7 +6571,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3090 "reflect.h2" +#line 3093 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6563,13 +6591,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3109 "reflect.h2" +#line 3112 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in uid) -> void { static_cast(uid); } -#line 3115 "reflect.h2" +#line 3118 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in qid) -> void { for ( @@ -6579,7 +6607,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3125 "reflect.h2" +#line 3128 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in tid) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6596,7 +6624,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 3142 "reflect.h2" +#line 3145 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6616,7 +6644,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}}} } -#line 3162 "reflect.h2" +#line 3165 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in idexpr) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6633,7 +6661,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 3180 "reflect.h2" +#line 3183 "reflect.h2" //----------------------------------------------------------------------- // // sample_traverser serves two purposes: @@ -6644,7 +6672,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // for reflecting on function bodies (statements, expressions) // -#line 3190 "reflect.h2" +#line 3193 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void { sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); @@ -6666,7 +6694,7 @@ auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in f, cpp2::impl::in indent) -> void { sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); @@ -6696,7 +6724,7 @@ auto sample_traverser(cpp2::impl::in f, cpp2::impl:: } } -#line 3242 "reflect.h2" +#line 3245 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void { sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); @@ -6706,7 +6734,7 @@ auto sample_traverser(cpp2::impl::in o, cpp2::impl::in } } -#line 3252 "reflect.h2" +#line 3255 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); @@ -6725,7 +6753,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("parameter:", indent); @@ -6744,7 +6772,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl: sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); } -#line 3290 "reflect.h2" +#line 3293 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6791,7 +6819,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in stmt, cpp2::impl::in indent) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6808,7 +6836,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl: } } -#line 3354 "reflect.h2" +#line 3357 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { sample_print("return statement", indent); @@ -6818,7 +6846,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::i } } -#line 3364 "reflect.h2" +#line 3367 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6850,7 +6878,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl } } -#line 3396 "reflect.h2" +#line 3399 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void { // An expression has other shortcuts to query deeper properties, @@ -6864,7 +6892,7 @@ auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6882,7 +6910,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3426 "reflect.h2" +#line 3429 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6894,11 +6922,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3436 "reflect.h2" +#line 3439 "reflect.h2" } } -#line 3440 "reflect.h2" +#line 3443 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6916,7 +6944,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3456 "reflect.h2" +#line 3459 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6928,11 +6956,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3466 "reflect.h2" +#line 3469 "reflect.h2" } } -#line 3470 "reflect.h2" +#line 3473 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6950,7 +6978,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2 { auto first{true}; -#line 3486 "reflect.h2" +#line 3489 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6962,11 +6990,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3496 "reflect.h2" +#line 3499 "reflect.h2" } } -#line 3500 "reflect.h2" +#line 3503 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6984,7 +7012,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::imp { auto first{true}; -#line 3516 "reflect.h2" +#line 3519 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6996,11 +7024,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3526 "reflect.h2" +#line 3529 "reflect.h2" } } -#line 3530 "reflect.h2" +#line 3533 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7018,7 +7046,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3546 "reflect.h2" +#line 3549 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7030,11 +7058,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3556 "reflect.h2" +#line 3559 "reflect.h2" } } -#line 3560 "reflect.h2" +#line 3563 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7052,7 +7080,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3576 "reflect.h2" +#line 3579 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7064,11 +7092,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3586 "reflect.h2" +#line 3589 "reflect.h2" } } -#line 3590 "reflect.h2" +#line 3593 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7086,7 +7114,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3606 "reflect.h2" +#line 3609 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7098,11 +7126,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3616 "reflect.h2" +#line 3619 "reflect.h2" } } -#line 3620 "reflect.h2" +#line 3623 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7120,7 +7148,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3636 "reflect.h2" +#line 3639 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7132,11 +7160,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3646 "reflect.h2" +#line 3649 "reflect.h2" } } -#line 3650 "reflect.h2" +#line 3653 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7154,7 +7182,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3666 "reflect.h2" +#line 3669 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7166,11 +7194,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3676 "reflect.h2" +#line 3679 "reflect.h2" } } -#line 3680 "reflect.h2" +#line 3683 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7188,7 +7216,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl { auto first{true}; -#line 3696 "reflect.h2" +#line 3699 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7200,11 +7228,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3706 "reflect.h2" +#line 3709 "reflect.h2" } } -#line 3710 "reflect.h2" +#line 3713 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7222,7 +7250,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3726 "reflect.h2" +#line 3729 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7234,11 +7262,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3736 "reflect.h2" +#line 3739 "reflect.h2" } } -#line 3740 "reflect.h2" +#line 3743 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7256,7 +7284,7 @@ auto sample_traverser(cpp2::impl::in binexpr, c { auto first{true}; -#line 3756 "reflect.h2" +#line 3759 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7268,11 +7296,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3766 "reflect.h2" +#line 3769 "reflect.h2" } } -#line 3770 "reflect.h2" +#line 3773 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -7298,7 +7326,7 @@ auto sample_traverser(cpp2::impl::in isas, cpp2::impl::i } } -#line 3796 "reflect.h2" +#line 3799 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_empty)(exprs)) { @@ -7313,7 +7341,7 @@ auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::i } } -#line 3811 "reflect.h2" +#line 3814 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -7337,7 +7365,7 @@ auto sample_traverser(cpp2::impl::in prefix, cpp2::impl } } -#line 3835 "reflect.h2" +#line 3838 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7370,7 +7398,7 @@ auto sample_traverser(cpp2::impl::in postfix, cpp2::im } } -#line 3868 "reflect.h2" +#line 3871 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(uid)) { @@ -7381,13 +7409,13 @@ auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in qid, cpp2::impl::in indent) -> void { { auto first{true}; -#line 3882 "reflect.h2" +#line 3885 "reflect.h2" for ( auto const& term : CPP2_UFCS(get_terms)(qid) ) { @@ -7399,10 +7427,10 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_unqualified)(term), indent + 2); } } -#line 3892 "reflect.h2" +#line 3895 "reflect.h2" } -#line 3895 "reflect.h2" +#line 3898 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -7419,7 +7447,7 @@ auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in primary, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7439,7 +7467,7 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im }}}} } -#line 3932 "reflect.h2" +#line 3935 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -7456,13 +7484,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}} } -#line 3949 "reflect.h2" +#line 3952 "reflect.h2" //----------------------------------------------------------------------- // // autodiff - stub // -#line 3963 "reflect.h2" +#line 3966 "reflect.h2" autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_, cpp2::impl::in code_higher_order_) : name{ name_ } , n_args{ n_args_ } @@ -7471,13 +7499,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , code{ code_ } , code_higher_order{ code_higher_order_ }{ -#line 3971 "reflect.h2" +#line 3974 "reflect.h2" if (CPP2_UFCS(empty)(code_higher_order)) { code_higher_order = code; } } -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) : name{ that.name } , n_args{ that.n_args } @@ -7485,7 +7513,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , is_member{ that.is_member } , code{ that.code } , code_higher_order{ that.code_higher_order }{} -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { name = that.name; n_args = that.n_args; @@ -7494,7 +7522,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in code = that.code; code_higher_order = that.code_higher_order; return *this; } -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept : name{ std::move(that).name } , n_args{ std::move(that).n_args } @@ -7502,7 +7530,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , is_member{ std::move(that).is_member } , code{ std::move(that).code } , code_higher_order{ std::move(that).code_higher_order }{} -#line 3976 "reflect.h2" +#line 3979 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { name = std::move(that).name; n_args = std::move(that).n_args; @@ -7512,18 +7540,26 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in code_higher_order = std::move(that).code_higher_order; return *this; }// Default copy. -#line 3978 "reflect.h2" +#line 3981 "reflect.h2" [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; } -#line 3984 "reflect.h2" - // namespace + type name - #line 3987 "reflect.h2" + // namespace + type name + +#line 3993 "reflect.h2" + autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) + : full_name{ full_name_ } + , decl{ decl_ }{ + +#line 3996 "reflect.h2" + } + +#line 3998 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 3988 "reflect.h2" +#line 3999 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -7533,12 +7569,18 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return r; } - autodiff_declaration_stack_item::autodiff_declaration_stack_item(auto&& full_name_, auto&& decl_) -requires (std::is_convertible_v&> && std::is_convertible_v&>) - : full_name{ CPP2_FORWARD(full_name_) } - , decl{ CPP2_FORWARD(decl_) }{} + autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that) + : full_name{ that.full_name } + , decl{ that.decl } + , diff_request{ that.diff_request } + , diff_done{ that.diff_done }{} +autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept + : full_name{ std::move(that).full_name } + , decl{ std::move(that).decl } + , diff_request{ std::move(that).diff_request } + , diff_done{ std::move(that).diff_done }{} -#line 4001 "reflect.h2" +#line 4012 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7551,19 +7593,19 @@ requires (std::is_convertible_v t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -7578,10 +7620,10 @@ requires (std::is_convertible_v(CPP2_UFCS(emplace_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); + static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4062 "reflect.h2" +#line 4073 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7593,17 +7635,17 @@ requires (std::is_convertible_v decltype(auto) { return order != 1; } -#line 4075 "reflect.h2" +#line 4086 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4081 "reflect.h2" +#line 4092 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ if (order == 1) { @@ -7613,10 +7655,10 @@ requires (std::is_convertible_v decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4091 "reflect.h2" +#line 4102 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7639,10 +7681,10 @@ requires (std::is_convertible_v decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4114 "reflect.h2" +#line 4125 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7652,11 +7694,11 @@ requires (std::is_convertible_v func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4124 "reflect.h2" +#line 4135 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7675,36 +7717,102 @@ requires (std::is_convertible_v t) & -> void{ + auto top {&CPP2_UFCS(back)(declaration_stack)}; + + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_same)(CPP2_UFCS(get_parent)(t), (*cpp2::impl::assert_not_null(top)).decl)) ) { cpp2::cpp2_default.report_violation(""); } + + CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); + } + +#line 4161 "reflect.h2" + auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ + auto t_parent {CPP2_UFCS(get_parent)(t)}; + + auto found {false}; + for ( auto& cur : std::ranges::views::reverse(declaration_stack) ) { + if (CPP2_UFCS(is_same)(t_parent, cur.decl)) { + if (!(is_in_list(t, cur.diff_request))) { + CPP2_UFCS(push_back)(cur.diff_request, t); + } + + found = true; + break; + } + } + + if (!(cpp2::move(found))) { + CPP2_UFCS(error)(t, "AD: Could not find parent type/namespace for: " + cpp2::to_string(t) + ""); + } + } + +#line 4181 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ + for ( auto const& cur : list ) { + if (CPP2_UFCS(is_same)(cur, v)) { + return true; + } + } + + return false; + } + +#line 4191 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4146 "reflect.h2" +#line 4195 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4155 "reflect.h2" +#line 4198 "reflect.h2" + auto autodiff_context::pop_stack() & -> void{ + if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } + + auto top {&CPP2_UFCS(back)(declaration_stack)}; + + for ( auto const& cur : (*cpp2::impl::assert_not_null(top)).diff_request ) { + if (!(is_in_list(cur, (*cpp2::impl::assert_not_null(top)).diff_done))) { + // TODO: Implement declaration diff handling + // ad: autodiff_declaration_handler = (this); + // ad.pre_traverse(cur); + CPP2_UFCS(error)((*cpp2::impl::assert_not_null(top)).decl, "AD: diff for `" + cpp2::to_string(CPP2_UFCS(name)(cur)) + "` in `" + cpp2::to_string(CPP2_UFCS(name)((*cpp2::impl::assert_not_null(top)).decl)) + "` requested."); + } + } + + CPP2_UFCS(pop_back)(declaration_stack); + } + +#line 4215 "reflect.h2" + auto autodiff_context::finish() & -> void{ + while( !(CPP2_UFCS(empty)(declaration_stack)) ) { + pop_stack(); + } + } + +#line 4227 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4157 "reflect.h2" +#line 4229 "reflect.h2" } -#line 4155 "reflect.h2" +#line 4227 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4157 "reflect.h2" +#line 4229 "reflect.h2" } -#line 4159 "reflect.h2" +#line 4231 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4174 "reflect.h2" +#line 4246 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7712,13 +7820,13 @@ requires (std::is_convertible_v prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7738,7 +7846,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7748,7 +7856,7 @@ requires (std::is_convertible_v std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7787,7 +7895,7 @@ requires (std::is_convertible_v postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7795,7 +7903,7 @@ requires (std::is_convertible_v object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -7941,75 +8051,75 @@ auto i{0}; { auto i{1}; -#line 4394 "reflect.h2" +#line 4468 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4399 "reflect.h2" +#line 4473 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4404 "reflect.h2" +#line 4478 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4408 "reflect.h2" +#line 4482 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4412 "reflect.h2" +#line 4486 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4416 "reflect.h2" +#line 4490 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4420 "reflect.h2" +#line 4494 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4424 "reflect.h2" +#line 4498 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4428 "reflect.h2" +#line 4502 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4432 "reflect.h2" +#line 4506 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4436 "reflect.h2" +#line 4510 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4440 "reflect.h2" +#line 4514 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4444 "reflect.h2" +#line 4518 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4448 "reflect.h2" +#line 4522 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8034,7 +8144,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4472 "reflect.h2" +#line 4546 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8073,7 +8183,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4511 "reflect.h2" +#line 4585 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -8092,18 +8202,18 @@ auto i{1}; } } -#line 4529 "reflect.h2" +#line 4603 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4533 "reflect.h2" +#line 4607 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4538 "reflect.h2" +#line 4612 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8112,7 +8222,7 @@ auto i{1}; { auto i{0}; -#line 4545 "reflect.h2" +#line 4619 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8126,7 +8236,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4557 "reflect.h2" +#line 4631 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8135,7 +8245,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4565 "reflect.h2" +#line 4639 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8168,26 +8278,26 @@ auto i{0}; }}}} } -#line 4606 "reflect.h2" +#line 4680 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4609 "reflect.h2" +#line 4683 "reflect.h2" } -#line 4611 "reflect.h2" +#line 4685 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4616 "reflect.h2" +#line 4690 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4621 "reflect.h2" +#line 4695 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8205,22 +8315,22 @@ auto i{0}; } } -#line 4639 "reflect.h2" +#line 4713 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4644 "reflect.h2" +#line 4718 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4649 "reflect.h2" +#line 4723 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4654 "reflect.h2" +#line 4728 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8228,7 +8338,7 @@ auto i{0}; diff += "}\n"; } -#line 4662 "reflect.h2" +#line 4736 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8244,7 +8354,7 @@ auto i{0}; } } -#line 4678 "reflect.h2" +#line 4752 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8291,7 +8401,7 @@ auto i{0}; }} } -#line 4725 "reflect.h2" +#line 4799 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8303,7 +8413,7 @@ auto i{0}; } } -#line 4736 "reflect.h2" +#line 4810 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8332,79 +8442,79 @@ auto i{0}; } } -#line 4764 "reflect.h2" +#line 4838 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4769 "reflect.h2" +#line 4843 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4773 "reflect.h2" +#line 4847 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4777 "reflect.h2" +#line 4851 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4781 "reflect.h2" +#line 4855 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4785 "reflect.h2" +#line 4859 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4789 "reflect.h2" +#line 4863 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4793 "reflect.h2" +#line 4867 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4797 "reflect.h2" +#line 4871 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4801 "reflect.h2" +#line 4875 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4805 "reflect.h2" +#line 4879 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4809 "reflect.h2" +#line 4883 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4813 "reflect.h2" +#line 4887 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4817 "reflect.h2" +#line 4891 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4822 "reflect.h2" +#line 4896 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8413,7 +8523,7 @@ auto i{0}; { auto i{0}; -#line 4829 "reflect.h2" +#line 4903 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8427,7 +8537,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4841 "reflect.h2" +#line 4915 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8438,13 +8548,13 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4851 "reflect.h2" +#line 4925 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4857 "reflect.h2" +#line 4931 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8530,11 +8640,11 @@ auto autodiff(meta::type_declaration& t) -> void return ; } -#line 4943 "reflect.h2" +#line 5017 "reflect.h2" autodiff_stmt_handler ad_impl {&ad_ctx, mf}; -#line 4946 "reflect.h2" - for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(cpp2::move(mf))) ) +#line 5020 "reflect.h2" + for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) { ad_impl.pre_traverse(stmt); } @@ -8545,11 +8655,17 @@ auto autodiff(meta::type_declaration& t) -> void CPP2_UFCS(leave_function)(ad_ctx); CPP2_UFCS(add_member)(t, cpp2::move(diff)); + + CPP2_UFCS(add_as_differentiated)(ad_ctx, cpp2::move(mf)); } if (1 != cpp2::move(order)) { CPP2_UFCS(add_runtime_support_include)(t, "cpp2taylor.h"); } + + CPP2_UFCS(finish)(ad_ctx); + + static_cast(cpp2::move(ad_ctx)); } @@ -8643,7 +8759,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 4965 "reflect.h2" +#line 5045 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8659,11 +8775,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 4981 "reflect.h2" +#line 5061 "reflect.h2" // Possible modifiers for a regular expression. // -#line 4985 "reflect.h2" +#line 5065 "reflect.h2" // mod: i // mod: m // mod: s @@ -8671,116 +8787,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 4994 "reflect.h2" +#line 5074 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5003 "reflect.h2" +#line 5083 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5005 "reflect.h2" +#line 5085 "reflect.h2" } -#line 5007 "reflect.h2" +#line 5087 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5009 "reflect.h2" +#line 5089 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5015 "reflect.h2" +#line 5095 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5016 "reflect.h2" +#line 5096 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5017 "reflect.h2" +#line 5097 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5032 "reflect.h2" +#line 5112 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5035 "reflect.h2" +#line 5115 "reflect.h2" } -#line 5037 "reflect.h2" +#line 5117 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5041 "reflect.h2" +#line 5121 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5053 "reflect.h2" +#line 5133 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5056 "reflect.h2" +#line 5136 "reflect.h2" } -#line 5058 "reflect.h2" +#line 5138 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5062 "reflect.h2" +#line 5142 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5072 "reflect.h2" +#line 5152 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5074 "reflect.h2" +#line 5154 "reflect.h2" } -#line 5076 "reflect.h2" +#line 5156 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5080 "reflect.h2" +#line 5160 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5092 "reflect.h2" +#line 5172 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5095 "reflect.h2" +#line 5175 "reflect.h2" } -#line 5097 "reflect.h2" +#line 5177 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5103 "reflect.h2" +#line 5183 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5109 "reflect.h2" +#line 5189 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8789,7 +8905,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5117 "reflect.h2" +#line 5197 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8805,7 +8921,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5145 "reflect.h2" +#line 5225 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8813,14 +8929,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5153 "reflect.h2" +#line 5233 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5160 "reflect.h2" +#line 5240 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8832,15 +8948,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5172 "reflect.h2" +#line 5252 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5177 "reflect.h2" +#line 5257 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5181 "reflect.h2" +#line 5261 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8861,7 +8977,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5207 "reflect.h2" +#line 5287 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8870,20 +8986,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5216 "reflect.h2" +#line 5296 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5222 "reflect.h2" +#line 5302 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5229 "reflect.h2" +#line 5309 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -8898,16 +9014,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5259 "reflect.h2" +#line 5339 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5263 "reflect.h2" +#line 5343 "reflect.h2" } -#line 5269 "reflect.h2" +#line 5349 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -8917,7 +9033,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5279 "reflect.h2" +#line 5359 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -8925,17 +9041,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5286 "reflect.h2" +#line 5366 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5290 "reflect.h2" +#line 5370 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5297 "reflect.h2" +#line 5377 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -8945,7 +9061,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5306 "reflect.h2" +#line 5386 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -8953,24 +9069,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5313 "reflect.h2" +#line 5393 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5321 "reflect.h2" +#line 5401 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5325 "reflect.h2" +#line 5405 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5329 "reflect.h2" +#line 5409 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -8982,22 +9098,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5340 "reflect.h2" +#line 5420 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5346 "reflect.h2" +#line 5426 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5350 "reflect.h2" +#line 5430 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5354 "reflect.h2" +#line 5434 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9005,7 +9121,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5361 "reflect.h2" +#line 5441 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9017,10 +9133,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5374 "reflect.h2" +#line 5454 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5377 "reflect.h2" +#line 5457 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9060,7 +9176,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5417 "reflect.h2" +#line 5497 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9072,14 +9188,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5428 "reflect.h2" +#line 5508 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5429 "reflect.h2" +#line 5509 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5430 "reflect.h2" +#line 5510 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5432 "reflect.h2" +#line 5512 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9089,10 +9205,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5441 "reflect.h2" +#line 5521 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5443 "reflect.h2" +#line 5523 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9114,14 +9230,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5464 "reflect.h2" +#line 5544 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5465 "reflect.h2" +#line 5545 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5466 "reflect.h2" +#line 5546 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5468 "reflect.h2" +#line 5548 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9135,7 +9251,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5481 "reflect.h2" +#line 5561 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9157,7 +9273,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5502 "reflect.h2" +#line 5582 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9168,12 +9284,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5512 "reflect.h2" +#line 5592 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5513 "reflect.h2" +#line 5593 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5518 "reflect.h2" +#line 5598 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9228,7 +9344,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5572 "reflect.h2" +#line 5652 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9268,7 +9384,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5611 "reflect.h2" +#line 5691 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9284,21 +9400,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5628 "reflect.h2" +#line 5708 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5629 "reflect.h2" +#line 5709 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5630 "reflect.h2" +#line 5710 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5632 "reflect.h2" +#line 5712 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5647 "reflect.h2" +#line 5727 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9306,7 +9422,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5654 "reflect.h2" +#line 5734 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9316,22 +9432,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5672 "reflect.h2" +#line 5752 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5677 "reflect.h2" +#line 5757 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5683 "reflect.h2" +#line 5763 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5689 "reflect.h2" +#line 5769 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9340,7 +9456,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5697 "reflect.h2" +#line 5777 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9352,7 +9468,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5708 "reflect.h2" +#line 5788 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9360,7 +9476,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5715 "reflect.h2" +#line 5795 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9381,7 +9497,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5736 "reflect.h2" +#line 5816 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9391,7 +9507,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5746 "reflect.h2" +#line 5826 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9414,33 +9530,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5770 "reflect.h2" +#line 5850 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5776 "reflect.h2" +#line 5856 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5780 "reflect.h2" +#line 5860 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5786 "reflect.h2" +#line 5866 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5794 "reflect.h2" +#line 5874 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9449,7 +9565,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5802 "reflect.h2" +#line 5882 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9458,22 +9574,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5812 "reflect.h2" +#line 5892 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5816 "reflect.h2" +#line 5896 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5820 "reflect.h2" +#line 5900 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5824 "reflect.h2" +#line 5904 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9497,18 +9613,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5849 "reflect.h2" +#line 5929 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5864 "reflect.h2" +#line 5944 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5866 "reflect.h2" +#line 5946 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9519,15 +9635,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5881 "reflect.h2" +#line 5961 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5884 "reflect.h2" +#line 5964 "reflect.h2" } -#line 5886 "reflect.h2" +#line 5966 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9545,7 +9661,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5903 "reflect.h2" +#line 5983 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9553,7 +9669,7 @@ generation_function_context::generation_function_context(){} } } -#line 5910 "reflect.h2" +#line 5990 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9567,7 +9683,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5923 "reflect.h2" +#line 6003 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9583,14 +9699,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 5944 "reflect.h2" +#line 6024 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 5946 "reflect.h2" +#line 6026 "reflect.h2" } -#line 5948 "reflect.h2" +#line 6028 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9599,11 +9715,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 5963 "reflect.h2" +#line 6043 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 5965 "reflect.h2" +#line 6045 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9611,7 +9727,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 5972 "reflect.h2" +#line 6052 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9620,37 +9736,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 5980 "reflect.h2" +#line 6060 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 5994 "reflect.h2" +#line 6074 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 5998 "reflect.h2" +#line 6078 "reflect.h2" } -#line 6000 "reflect.h2" +#line 6080 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6004 "reflect.h2" +#line 6084 "reflect.h2" } -#line 6006 "reflect.h2" +#line 6086 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6010 "reflect.h2" +#line 6090 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9659,14 +9775,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6016 "reflect.h2" +#line 6096 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6021 "reflect.h2" +#line 6101 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9679,7 +9795,7 @@ size_t i{0}; } } -#line 6033 "reflect.h2" +#line 6113 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9701,7 +9817,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6054 "reflect.h2" +#line 6134 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9720,7 +9836,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6072 "reflect.h2" +#line 6152 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9736,14 +9852,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6087 "reflect.h2" +#line 6167 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6093 "reflect.h2" +#line 6173 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9751,19 +9867,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6110 "reflect.h2" +#line 6190 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6111 "reflect.h2" +#line 6191 "reflect.h2" { -#line 6116 "reflect.h2" +#line 6196 "reflect.h2" } -#line 6119 "reflect.h2" +#line 6199 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -9889,7 +10005,7 @@ size_t i{0}; ); } -#line 6244 "reflect.h2" +#line 6324 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -9899,13 +10015,13 @@ size_t i{0}; ); } -#line 6253 "reflect.h2" +#line 6333 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6258 "reflect.h2" +#line 6338 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -9916,12 +10032,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6270 "reflect.h2" +#line 6350 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6275 "reflect.h2" +#line 6355 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -9955,7 +10071,7 @@ size_t i{0}; } -#line 6311 "reflect.h2" +#line 6391 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -9964,19 +10080,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6334 "reflect.h2" +#line 6414 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6335 "reflect.h2" +#line 6415 "reflect.h2" { -#line 6340 "reflect.h2" +#line 6420 "reflect.h2" } -#line 6342 "reflect.h2" +#line 6422 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10078,19 +10194,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6443 "reflect.h2" +#line 6523 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6447 "reflect.h2" +#line 6527 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6471 "reflect.h2" +#line 6551 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10109,7 +10225,7 @@ size_t i{0}; return r; } -#line 6489 "reflect.h2" +#line 6569 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10124,7 +10240,7 @@ size_t i{0}; return r; } -#line 6503 "reflect.h2" +#line 6583 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10284,7 +10400,7 @@ size_t i{0}; } } -#line 6662 "reflect.h2" +#line 6742 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10293,7 +10409,7 @@ size_t i{0}; return r; } -#line 6670 "reflect.h2" +#line 6750 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10312,7 +10428,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6688 "reflect.h2" +#line 6768 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10344,7 +10460,7 @@ size_t i{0}; } } -#line 6719 "reflect.h2" +#line 6799 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10355,7 +10471,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6731 "reflect.h2" +#line 6811 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10394,7 +10510,7 @@ size_t i{0}; return r; } -#line 6772 "reflect.h2" +#line 6852 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10412,7 +10528,7 @@ size_t i{0}; }} } -#line 6792 "reflect.h2" +#line 6872 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10426,16 +10542,16 @@ size_t i{0}; } } -#line 6818 "reflect.h2" +#line 6898 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6821 "reflect.h2" +#line 6901 "reflect.h2" } -#line 6823 "reflect.h2" +#line 6903 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10447,7 +10563,7 @@ size_t i{0}; } } -#line 6834 "reflect.h2" +#line 6914 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10455,14 +10571,14 @@ size_t i{0}; return r; } -#line 6841 "reflect.h2" +#line 6921 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6849 "reflect.h2" +#line 6929 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10488,7 +10604,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6877 "reflect.h2" +#line 6957 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10514,11 +10630,11 @@ size_t i{0}; return r; } -#line 6914 "reflect.h2" +#line 6994 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6916 "reflect.h2" +#line 6996 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10592,7 +10708,7 @@ size_t i{0}; return nullptr; } -#line 6989 "reflect.h2" +#line 7069 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10605,7 +10721,7 @@ size_t i{0}; }} } -#line 7001 "reflect.h2" +#line 7081 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10619,7 +10735,7 @@ size_t i{0}; }} } -#line 7014 "reflect.h2" +#line 7094 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10639,7 +10755,7 @@ size_t i{0}; return r; } -#line 7033 "reflect.h2" +#line 7113 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10650,7 +10766,7 @@ size_t i{0}; return r; } -#line 7043 "reflect.h2" +#line 7123 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10662,14 +10778,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7054 "reflect.h2" +#line 7134 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7066 "reflect.h2" +#line 7146 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10693,7 +10809,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7090 "reflect.h2" +#line 7170 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10703,7 +10819,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7102 "reflect.h2" +#line 7182 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10719,7 +10835,7 @@ size_t i{0}; } } -#line 7122 "reflect.h2" +#line 7202 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10737,15 +10853,15 @@ size_t i{0}; }} } -#line 7158 "reflect.h2" +#line 7238 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7161 "reflect.h2" +#line 7241 "reflect.h2" } -#line 7163 "reflect.h2" +#line 7243 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10781,7 +10897,7 @@ size_t i{0}; return source; } -#line 7198 "reflect.h2" +#line 7278 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10797,7 +10913,7 @@ size_t i{0}; } } -#line 7214 "reflect.h2" +#line 7294 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10806,7 +10922,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10861,7 +10977,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7283 "reflect.h2" +#line 7363 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -10983,7 +11099,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7405 "reflect.h2" +#line 7485 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 3e4f6675f..b13eae503 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -206,6 +206,9 @@ reflection_base: @polymorphic_base @copy_constructible type = position: (override this) -> source_position = n*.position(); print: (this) -> std::string = n*.pretty_print_visualize(0); + + is_same: (this, o: reflection_base) -> bool = n == o.n; // Test pointers + is_same: (this, o: reflection_base) -> bool = false; // Different types => false } @@ -3980,9 +3983,17 @@ autodiff_special_func: type = { } } -autodiff_declaration_stack_item: @struct type = { - full_name: std::string; // namespace + type name - decl: meta::type_or_namespace_declaration; +autodiff_declaration_stack_item: @copy_constructible type = { + public full_name: std::string; // namespace + type name + public decl: meta::type_or_namespace_declaration; + + public diff_request: std::vector = (); + public diff_done: std::vector = (); + + operator=: (out this, full_name_: std::string, decl_: meta::type_or_namespace_declaration) = { + full_name = full_name_; + decl = decl_; + } lookup_declaration: (this, decl_name: std::string) -> (r: std::vector = ()) = { for decl.get_members() do (cur) { @@ -4056,7 +4067,7 @@ autodiff_context: type = { } full_name += t.name(); - _ = declaration_stack.emplace_back(autodiff_declaration_stack_item(full_name, t)); + _ = declaration_stack.push_back(autodiff_declaration_stack_item(full_name, t)); } set_order : (inout this, new_order: int) = { @@ -4139,12 +4150,73 @@ autodiff_context: type = { } } + add_as_differentiated: (inout this, t: meta::declaration) = { + top := declaration_stack.back()&; + + assert(t.get_parent().is_same(top*.decl)); + + top*.diff_done.push_back(t); + } + + add_for_differentiation: (inout this, t: meta::declaration) = { + t_parent := t.get_parent(); + + found := false; + for std::ranges::views::reverse(declaration_stack) do (inout cur) { + if t_parent.is_same(cur.decl) { + if !is_in_list(t, cur.diff_request) { + cur.diff_request.push_back(t); + } + + found = true; + break; + } + } + + if !found { + t.error("AD: Could not find parent type/namespace for: (t)$"); + } + } + + is_in_list: (v: meta::declaration, list: std::vector) -> bool = { + for list do (cur) { + if cur.is_same(v) { + return true; + } + } + + return false; + } + enter_function: (inout this) = { temporary_count = 0; } leave_function: (inout this) = { } + + pop_stack: (inout this) = { + assert(!declaration_stack.empty()); + + top := declaration_stack.back()&; + + for top*.diff_request do (cur) { + if !is_in_list(cur, top*.diff_done) { + // TODO: Implement declaration diff handling + // ad: autodiff_declaration_handler = (this); + // ad.pre_traverse(cur); + top*.decl.error("AD: diff for `(cur.name())$` in `(top*.decl.name())$` requested."); + } + } + + declaration_stack.pop_back(); + } + + finish: (inout this) = { + while !declaration_stack.empty() { + pop_stack(); + } + } } autodiff_handler_base: type = { @@ -4363,9 +4435,11 @@ autodiff_expression_handler: type = { ret_name_d : std::string = ret_name + ctx*.suffix; gen_lhs_assignment("(ret_temp)$.(ret_name)$", "(ret_temp)$.(ret_name_d)$", /* switch order = */ true); + + ctx*.add_for_differentiation(functions[0]); } - // TODO: Add function to list of functions/objects for differentiation. + // TODO: Add function to list of functions/objects for differentiation for the no return case. } handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector, ret: std::string) -> bool = { @@ -4954,11 +5028,17 @@ autodiff: (inout t: meta::type_declaration) = ad_ctx.leave_function(); t.add_member( diff ); + + ad_ctx.add_as_differentiated(mf); } if 1 != order { t.add_runtime_support_include( "cpp2taylor.h" ); } + + ad_ctx.finish(); + + _ = ad_ctx; } From 92d2407a4cde7c62addb54dee34d24428e9a76f9 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 15 Aug 2025 13:24:56 +0200 Subject: [PATCH 29/54] Moved handling of types and functions to autodiff_declaration_handler. --- regression-tests/pure2-autodiff.cpp2 | 52 +- .../test-results/pure2-autodiff.cpp | 233 +-- source/reflect.h | 1264 +++++++++-------- source/reflect.h2 | 192 ++- 4 files changed, 980 insertions(+), 761 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index cfdd71f40..6adc88238 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -1,3 +1,4 @@ +ad_name: namespace = { ad_test: @autodiff @print type = { @@ -151,6 +152,7 @@ ad_test: @autodiff @print type = { } } } +} ad_test_twice: @autodiff @autodiff<"suffix=_d2"> @print type = { mul_1: (x: double) -> (r: double) = { @@ -169,31 +171,31 @@ main: () = { y: double = 3.0; y_d: double = 2.0; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("x + y", x, x_d, y, y_d, ad_name::ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_name::ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_name::ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_name::ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_name::ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_name::ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_name::ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_name::ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_name::ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_name::ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_name::ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_name::ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_name::ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_name::ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_name::ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 1cc062ec2..91d7ddff4 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -7,147 +7,151 @@ #include "cpp2util.h" #line 1 "pure2-autodiff.cpp2" +namespace ad_name { -#line 2 "pure2-autodiff.cpp2" +#line 3 "pure2-autodiff.cpp2" class ad_test; #line 155 "pure2-autodiff.cpp2" +} + class ad_test_twice; //=== Cpp2 type definitions and function declarations =========================== #line 1 "pure2-autodiff.cpp2" +namespace ad_name { -#line 2 "pure2-autodiff.cpp2" +#line 3 "pure2-autodiff.cpp2" class ad_test { using add_1_ret = double; -#line 4 "pure2-autodiff.cpp2" +#line 5 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 8 "pure2-autodiff.cpp2" +#line 9 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 12 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 16 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 20 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 24 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 28 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 32 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 36 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 40 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 44 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 48 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 52 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 56 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using sin_call_ret = double; -#line 60 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 64 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 72 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 81 "pure2-autodiff.cpp2" +#line 82 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 85 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 91 "pure2-autodiff.cpp2" +#line 92 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 99 "pure2-autodiff.cpp2" +#line 100 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 106 "pure2-autodiff.cpp2" +#line 107 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 113 "pure2-autodiff.cpp2" +#line 114 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 120 "pure2-autodiff.cpp2" +#line 121 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 129 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 140 "pure2-autodiff.cpp2" +#line 141 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_d_ret { double r; double r_d; }; @@ -259,13 +263,14 @@ public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test const&) -> void = delete; -#line 153 "pure2-autodiff.cpp2" +#line 154 "pure2-autodiff.cpp2" }; +} class ad_test_twice { using mul_1_ret = double; -#line 156 "pure2-autodiff.cpp2" +#line 158 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -285,127 +290,128 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 159 "pure2-autodiff.cpp2" +#line 161 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 165 "pure2-autodiff.cpp2" +#line 167 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= #line 1 "pure2-autodiff.cpp2" +namespace ad_name { -#line 4 "pure2-autodiff.cpp2" +#line 5 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 5 "pure2-autodiff.cpp2" +#line 6 "pure2-autodiff.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 8 "pure2-autodiff.cpp2" +#line 9 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 9 "pure2-autodiff.cpp2" +#line 10 "pure2-autodiff.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 12 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 13 "pure2-autodiff.cpp2" +#line 14 "pure2-autodiff.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 16 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 17 "pure2-autodiff.cpp2" +#line 18 "pure2-autodiff.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 20 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 21 "pure2-autodiff.cpp2" +#line 22 "pure2-autodiff.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 24 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 25 "pure2-autodiff.cpp2" +#line 26 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 28 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 29 "pure2-autodiff.cpp2" +#line 30 "pure2-autodiff.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 32 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 33 "pure2-autodiff.cpp2" +#line 34 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 36 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 37 "pure2-autodiff.cpp2" +#line 38 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 40 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 41 "pure2-autodiff.cpp2" +#line 42 "pure2-autodiff.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 44 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 45 "pure2-autodiff.cpp2" +#line 46 "pure2-autodiff.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 48 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 49 "pure2-autodiff.cpp2" +#line 50 "pure2-autodiff.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 52 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 53 "pure2-autodiff.cpp2" +#line 54 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 56 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 57 "pure2-autodiff.cpp2" +#line 58 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 60 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 61 "pure2-autodiff.cpp2" +#line 62 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 64 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 65 "pure2-autodiff.cpp2" +#line 66 "pure2-autodiff.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -413,10 +419,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 72 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 73 "pure2-autodiff.cpp2" +#line 74 "pure2-autodiff.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -425,24 +431,24 @@ auto main() -> int; }return std::move(r.value()); } -#line 81 "pure2-autodiff.cpp2" +#line 82 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 85 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 86 "pure2-autodiff.cpp2" +#line 87 "pure2-autodiff.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 91 "pure2-autodiff.cpp2" +#line 92 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 92 "pure2-autodiff.cpp2" +#line 93 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -450,40 +456,40 @@ auto main() -> int; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 99 "pure2-autodiff.cpp2" +#line 100 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 100 "pure2-autodiff.cpp2" +#line 101 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 106 "pure2-autodiff.cpp2" +#line 107 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 107 "pure2-autodiff.cpp2" +#line 108 "pure2-autodiff.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 113 "pure2-autodiff.cpp2" +#line 114 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 114 "pure2-autodiff.cpp2" +#line 115 "pure2-autodiff.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 120 "pure2-autodiff.cpp2" +#line 121 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 121 "pure2-autodiff.cpp2" +#line 122 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -492,10 +498,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 129 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 130 "pure2-autodiff.cpp2" +#line 131 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -506,10 +512,10 @@ auto main() -> int; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 140 "pure2-autodiff.cpp2" +#line 141 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 141 "pure2-autodiff.cpp2" +#line 142 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -812,10 +818,13 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 156 "pure2-autodiff.cpp2" +#line 155 "pure2-autodiff.cpp2" +} + +#line 158 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 157 "pure2-autodiff.cpp2" +#line 159 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -852,12 +861,12 @@ auto temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 161 "pure2-autodiff.cpp2" +#line 163 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 165 "pure2-autodiff.cpp2" +#line 167 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -865,31 +874,31 @@ auto main() -> int{ double y {3.0}; double y_d {2.0}; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); + write_output("x + y", x, x_d, y, y_d, ad_name::ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_name::ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_name::ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_name::ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_name::ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_name::ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_name::ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_name::ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_name::ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_name::ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_name::ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_name::ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_name::ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_name::ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_name::ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); auto r_twice {ad_test_twice::mul_1_d_d2(x, x_d, cpp2::move(x_d), 0.0)}; std::cout << "2nd order diff of x*x at " + cpp2::to_string(cpp2::move(x)) + " = " + cpp2::to_string(cpp2::move(r_twice).r_d_d2) + "" << std::endl; diff --git a/source/reflect.h b/source/reflect.h index 33da6e13d..978d46f19 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -118,88 +118,91 @@ class autodiff_declaration_stack_item; class autodiff_context; -#line 4222 "reflect.h2" +#line 4235 "reflect.h2" class autodiff_handler_base; -#line 4236 "reflect.h2" +#line 4249 "reflect.h2" class autodiff_expression_handler; -#line 4672 "reflect.h2" +#line 4685 "reflect.h2" class autodiff_stmt_handler; -#line 5063 "reflect.h2" +#line 4944 "reflect.h2" +class autodiff_declaration_handler; + +#line 5149 "reflect.h2" class expression_flags; -#line 5079 "reflect.h2" +#line 5165 "reflect.h2" class regex_token; -#line 5106 "reflect.h2" +#line 5192 "reflect.h2" class regex_token_check; -#line 5127 "reflect.h2" +#line 5213 "reflect.h2" class regex_token_code; -#line 5148 "reflect.h2" +#line 5234 "reflect.h2" class regex_token_empty; -#line 5166 "reflect.h2" +#line 5252 "reflect.h2" class regex_token_list; -#line 5218 "reflect.h2" +#line 5304 "reflect.h2" class parse_context_group_state; -#line 5279 "reflect.h2" +#line 5365 "reflect.h2" class parse_context_branch_reset_state; -#line 5322 "reflect.h2" +#line 5408 "reflect.h2" class parse_context; -#line 5723 "reflect.h2" +#line 5809 "reflect.h2" class generation_function_context; -#line 5741 "reflect.h2" +#line 5827 "reflect.h2" class generation_context; -#line 5940 "reflect.h2" +#line 6026 "reflect.h2" class alternative_token; -#line 5955 "reflect.h2" +#line 6041 "reflect.h2" class alternative_token_gen; -#line 6020 "reflect.h2" +#line 6106 "reflect.h2" class any_token; -#line 6037 "reflect.h2" +#line 6123 "reflect.h2" class atomic_group_token; -#line 6067 "reflect.h2" +#line 6153 "reflect.h2" class char_token; -#line 6182 "reflect.h2" +#line 6268 "reflect.h2" class class_token; -#line 6406 "reflect.h2" +#line 6492 "reflect.h2" class group_ref_token; -#line 6543 "reflect.h2" +#line 6629 "reflect.h2" class group_token; -#line 6890 "reflect.h2" +#line 6976 "reflect.h2" class lookahead_lookbehind_token; -#line 6985 "reflect.h2" +#line 7071 "reflect.h2" class range_token; -#line 7142 "reflect.h2" +#line 7228 "reflect.h2" class special_range_token; -#line 7228 "reflect.h2" +#line 7314 "reflect.h2" template class regex_generator; -#line 7485 "reflect.h2" +#line 7571 "reflect.h2" } } @@ -1774,16 +1777,19 @@ struct lookup_special_function_handling_ret { bool m; std::string code; }; public: auto leave_function() & -> void; #line 4198 "reflect.h2" + public: auto push_stack(cpp2::impl::in decl) & -> void; + +#line 4211 "reflect.h2" public: auto pop_stack() & -> void; -#line 4215 "reflect.h2" +#line 4228 "reflect.h2" public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4220 "reflect.h2" +#line 4233 "reflect.h2" }; class autodiff_handler_base { @@ -1792,21 +1798,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4227 "reflect.h2" +#line 4240 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4231 "reflect.h2" +#line 4244 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4234 "reflect.h2" +#line 4247 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4240 "reflect.h2" +#line 4253 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1815,180 +1821,214 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4257 "reflect.h2" +#line 4270 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4276 "reflect.h2" +#line 4289 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4285 "reflect.h2" +#line 4298 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4323 "reflect.h2" +#line 4336 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4445 "reflect.h2" +#line 4458 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4478 "reflect.h2" +#line 4491 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4482 "reflect.h2" +#line 4495 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4486 "reflect.h2" +#line 4499 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4490 "reflect.h2" +#line 4503 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4494 "reflect.h2" +#line 4507 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4498 "reflect.h2" +#line 4511 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4502 "reflect.h2" +#line 4515 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4506 "reflect.h2" +#line 4519 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4510 "reflect.h2" +#line 4523 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4514 "reflect.h2" +#line 4527 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4518 "reflect.h2" +#line 4531 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4522 "reflect.h2" +#line 4535 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4546 "reflect.h2" +#line 4559 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4603 "reflect.h2" +#line 4616 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4607 "reflect.h2" +#line 4620 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4612 "reflect.h2" +#line 4625 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4639 "reflect.h2" +#line 4652 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4670 "reflect.h2" +#line 4683 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4676 "reflect.h2" +#line 4689 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4685 "reflect.h2" +#line 4698 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4690 "reflect.h2" +#line 4703 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4695 "reflect.h2" +#line 4708 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4713 "reflect.h2" +#line 4726 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4718 "reflect.h2" +#line 4731 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4723 "reflect.h2" +#line 4736 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4728 "reflect.h2" +#line 4741 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4736 "reflect.h2" +#line 4749 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4752 "reflect.h2" +#line 4765 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4799 "reflect.h2" +#line 4812 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4810 "reflect.h2" +#line 4823 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4838 "reflect.h2" +#line 4851 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4843 "reflect.h2" +#line 4856 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4847 "reflect.h2" +#line 4860 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4851 "reflect.h2" +#line 4864 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4855 "reflect.h2" +#line 4868 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4859 "reflect.h2" +#line 4872 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4863 "reflect.h2" +#line 4876 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4867 "reflect.h2" +#line 4880 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4871 "reflect.h2" +#line 4884 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4875 "reflect.h2" +#line 4888 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4879 "reflect.h2" +#line 4892 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4883 "reflect.h2" +#line 4896 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4887 "reflect.h2" +#line 4900 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4891 "reflect.h2" +#line 4904 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4896 "reflect.h2" +#line 4909 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4925 "reflect.h2" +#line 4938 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4929 "reflect.h2" +#line 4942 "reflect.h2" }; +class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { + +#line 4948 "reflect.h2" + public: using base = simple_traverser; + + private: meta::type_or_namespace_declaration decl; + + public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); + +#line 4957 "reflect.h2" + public: auto traverse(cpp2::impl::in decl) -> void override; + +#line 4962 "reflect.h2" + public: auto traverse(cpp2::impl::in f) -> void override; + +#line 5026 "reflect.h2" + public: auto traverse(cpp2::impl::in o) -> void override; + +#line 5031 "reflect.h2" + public: auto traverse(cpp2::impl::in t) -> void override; + +#line 5046 "reflect.h2" + public: auto traverse(cpp2::impl::in t) -> void override; + +#line 5051 "reflect.h2" + public: auto traverse(cpp2::impl::in stmt) -> void override; + public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_declaration_handler const&) -> void = delete; + + +#line 5054 "reflect.h2" +}; + +#line 5057 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5059 "reflect.h2" +#line 5145 "reflect.h2" using error_func = std::function x)>; -#line 5063 "reflect.h2" +#line 5149 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2023,20 +2063,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5071 "reflect.h2" +#line 5157 "reflect.h2" }; -#line 5079 "reflect.h2" +#line 5165 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5087 "reflect.h2" +#line 5173 "reflect.h2" public: explicit regex_token(); -#line 5092 "reflect.h2" +#line 5178 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2048,103 +2088,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5098 "reflect.h2" +#line 5184 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5104 "reflect.h2" +#line 5190 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5110 "reflect.h2" +#line 5196 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5117 "reflect.h2" +#line 5203 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5121 "reflect.h2" +#line 5207 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5122 "reflect.h2" +#line 5208 "reflect.h2" }; -#line 5125 "reflect.h2" +#line 5211 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5131 "reflect.h2" +#line 5217 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5138 "reflect.h2" +#line 5224 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5142 "reflect.h2" +#line 5228 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5143 "reflect.h2" +#line 5229 "reflect.h2" }; -#line 5146 "reflect.h2" +#line 5232 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5152 "reflect.h2" +#line 5238 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5156 "reflect.h2" +#line 5242 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5160 "reflect.h2" +#line 5246 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5161 "reflect.h2" +#line 5247 "reflect.h2" }; -#line 5164 "reflect.h2" +#line 5250 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5170 "reflect.h2" +#line 5256 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5177 "reflect.h2" +#line 5263 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5183 "reflect.h2" +#line 5269 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5189 "reflect.h2" +#line 5275 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5197 "reflect.h2" +#line 5283 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2152,10 +2192,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5209 "reflect.h2" +#line 5295 "reflect.h2" }; -#line 5212 "reflect.h2" +#line 5298 "reflect.h2" // // Parse and generation context. // @@ -2171,33 +2211,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5232 "reflect.h2" +#line 5318 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5239 "reflect.h2" +#line 5325 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5251 "reflect.h2" +#line 5337 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5256 "reflect.h2" +#line 5342 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5260 "reflect.h2" +#line 5346 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5274 "reflect.h2" +#line 5360 "reflect.h2" }; -#line 5277 "reflect.h2" +#line 5363 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2210,25 +2250,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5295 "reflect.h2" +#line 5381 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5301 "reflect.h2" +#line 5387 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5308 "reflect.h2" +#line 5394 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5315 "reflect.h2" +#line 5401 "reflect.h2" }; -#line 5318 "reflect.h2" +#line 5404 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2244,7 +2284,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5334 "reflect.h2" +#line 5420 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2252,64 +2292,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5345 "reflect.h2" +#line 5431 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5358 "reflect.h2" +#line 5444 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5366 "reflect.h2" +#line 5452 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5370 "reflect.h2" +#line 5456 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5374 "reflect.h2" +#line 5460 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5386 "reflect.h2" +#line 5472 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5393 "reflect.h2" +#line 5479 "reflect.h2" public: auto next_alternative() & -> void; -#line 5399 "reflect.h2" +#line 5485 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5405 "reflect.h2" +#line 5491 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5409 "reflect.h2" +#line 5495 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5420 "reflect.h2" +#line 5506 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5424 "reflect.h2" +#line 5510 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5430 "reflect.h2" +#line 5516 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5434 "reflect.h2" +#line 5520 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5441 "reflect.h2" +#line 5527 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5452 "reflect.h2" +#line 5538 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2317,51 +2357,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5496 "reflect.h2" +#line 5582 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5508 "reflect.h2" +#line 5594 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5521 "reflect.h2" +#line 5607 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5544 "reflect.h2" +#line 5630 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5561 "reflect.h2" +#line 5647 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5582 "reflect.h2" +#line 5668 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5592 "reflect.h2" +#line 5678 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5596 "reflect.h2" +#line 5682 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5652 "reflect.h2" +#line 5738 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5691 "reflect.h2" +#line 5777 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5706 "reflect.h2" +#line 5792 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2373,10 +2413,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5717 "reflect.h2" +#line 5803 "reflect.h2" }; -#line 5720 "reflect.h2" +#line 5806 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2386,16 +2426,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5734 "reflect.h2" +#line 5820 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5737 "reflect.h2" +#line 5823 "reflect.h2" }; -#line 5740 "reflect.h2" +#line 5826 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2415,68 +2455,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5762 "reflect.h2" +#line 5848 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5768 "reflect.h2" +#line 5854 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5777 "reflect.h2" +#line 5863 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5788 "reflect.h2" +#line 5874 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5795 "reflect.h2" +#line 5881 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5815 "reflect.h2" +#line 5901 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5825 "reflect.h2" +#line 5911 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5848 "reflect.h2" +#line 5934 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5856 "reflect.h2" +#line 5942 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5860 "reflect.h2" +#line 5946 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5866 "reflect.h2" +#line 5952 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5872 "reflect.h2" +#line 5958 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5882 "reflect.h2" +#line 5968 "reflect.h2" public: auto finish_context() & -> void; -#line 5890 "reflect.h2" +#line 5976 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5896 "reflect.h2" +#line 5982 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5900 "reflect.h2" +#line 5986 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5904 "reflect.h2" +#line 5990 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 5928 "reflect.h2" +#line 6014 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2484,7 +2524,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 5934 "reflect.h2" +#line 6020 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2504,27 +2544,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 5953 "reflect.h2" +#line 6039 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 5959 "reflect.h2" +#line 6045 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 5966 "reflect.h2" +#line 6052 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5983 "reflect.h2" +#line 6069 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5990 "reflect.h2" +#line 6076 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6003 "reflect.h2" +#line 6089 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2532,19 +2572,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6015 "reflect.h2" +#line 6101 "reflect.h2" }; -#line 6018 "reflect.h2" +#line 6104 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6024 "reflect.h2" +#line 6110 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6028 "reflect.h2" +#line 6114 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2552,7 +2592,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6033 "reflect.h2" +#line 6119 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2560,17 +2600,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6041 "reflect.h2" +#line 6127 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6052 "reflect.h2" +#line 6138 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6060 "reflect.h2" +#line 6146 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2578,7 +2618,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6063 "reflect.h2" +#line 6149 "reflect.h2" }; // Regex syntax: a @@ -2586,34 +2626,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6071 "reflect.h2" +#line 6157 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6080 "reflect.h2" +#line 6166 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6086 "reflect.h2" +#line 6172 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6090 "reflect.h2" +#line 6176 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6113 "reflect.h2" +#line 6199 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6134 "reflect.h2" +#line 6220 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6152 "reflect.h2" +#line 6238 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6167 "reflect.h2" +#line 6253 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6173 "reflect.h2" +#line 6259 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2621,33 +2661,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6177 "reflect.h2" +#line 6263 "reflect.h2" }; -#line 6180 "reflect.h2" +#line 6266 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6186 "reflect.h2" +#line 6272 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6198 "reflect.h2" +#line 6284 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6324 "reflect.h2" +#line 6410 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6333 "reflect.h2" +#line 6419 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6338 "reflect.h2" +#line 6424 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2655,20 +2695,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6345 "reflect.h2" +#line 6431 "reflect.h2" }; -#line 6348 "reflect.h2" +#line 6434 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6389 "reflect.h2" +#line 6475 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6400 "reflect.h2" +#line 6486 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2678,20 +2718,20 @@ class class_token class group_ref_token : public regex_token { -#line 6410 "reflect.h2" +#line 6496 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6422 "reflect.h2" +#line 6508 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6523 "reflect.h2" +#line 6609 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6527 "reflect.h2" +#line 6613 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2699,10 +2739,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6530 "reflect.h2" +#line 6616 "reflect.h2" }; -#line 6533 "reflect.h2" +#line 6619 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2716,29 +2756,29 @@ class group_ref_token class group_token : public regex_token { -#line 6547 "reflect.h2" +#line 6633 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6569 "reflect.h2" +#line 6655 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6583 "reflect.h2" +#line 6669 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6742 "reflect.h2" +#line 6828 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6750 "reflect.h2" +#line 6836 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6768 "reflect.h2" +#line 6854 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6799 "reflect.h2" +#line 6885 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2747,25 +2787,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6806 "reflect.h2" +#line 6892 "reflect.h2" }; -#line 6809 "reflect.h2" +#line 6895 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6850 "reflect.h2" +#line 6936 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6870 "reflect.h2" +#line 6956 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6886 "reflect.h2" +#line 6972 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2773,20 +2813,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6894 "reflect.h2" +#line 6980 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6903 "reflect.h2" +#line 6989 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6914 "reflect.h2" +#line 7000 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6921 "reflect.h2" +#line 7007 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2794,26 +2834,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 6924 "reflect.h2" +#line 7010 "reflect.h2" }; -#line 6927 "reflect.h2" +#line 7013 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 6955 "reflect.h2" +#line 7041 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 6983 "reflect.h2" +#line 7069 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 6989 "reflect.h2" +#line 7075 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2823,22 +2863,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7069 "reflect.h2" +#line 7155 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7081 "reflect.h2" +#line 7167 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7094 "reflect.h2" +#line 7180 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7113 "reflect.h2" +#line 7199 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7123 "reflect.h2" +#line 7209 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7134 "reflect.h2" +#line 7220 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2846,16 +2886,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7137 "reflect.h2" +#line 7223 "reflect.h2" }; -#line 7140 "reflect.h2" +#line 7226 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7146 "reflect.h2" +#line 7232 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2864,7 +2904,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7176 "reflect.h2" +#line 7262 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2873,14 +2913,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7198 "reflect.h2" +#line 7284 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7220 "reflect.h2" +#line 7306 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2901,24 +2941,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7243 "reflect.h2" +#line 7329 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7278 "reflect.h2" +#line 7364 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7292 "reflect.h2" +#line 7378 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7304 "reflect.h2" +#line 7390 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7359 "reflect.h2" +#line 7445 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2929,7 +2969,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7485 "reflect.h2" +#line 7571 "reflect.h2" } } @@ -7768,6 +7808,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } #line 4198 "reflect.h2" + auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ + std::string full_name {""}; + + if (!(CPP2_UFCS(empty)(declaration_stack))) { + full_name += CPP2_UFCS(back)(declaration_stack).full_name; + } + + full_name += "::"; + full_name += CPP2_UFCS(name)(decl); + + CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); + } + +#line 4211 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -7785,34 +7839,34 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4215 "reflect.h2" +#line 4228 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4227 "reflect.h2" +#line 4240 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4229 "reflect.h2" +#line 4242 "reflect.h2" } -#line 4227 "reflect.h2" +#line 4240 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4229 "reflect.h2" +#line 4242 "reflect.h2" } -#line 4231 "reflect.h2" +#line 4244 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4246 "reflect.h2" +#line 4259 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7820,13 +7874,13 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4252 "reflect.h2" +#line 4265 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4257 "reflect.h2" +#line 4270 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7846,7 +7900,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4276 "reflect.h2" +#line 4289 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7856,7 +7910,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return args; } -#line 4285 "reflect.h2" +#line 4298 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7895,7 +7949,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }} } -#line 4323 "reflect.h2" +#line 4336 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7903,7 +7957,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4329 "reflect.h2" +#line 4342 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7917,7 +7971,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4341 "reflect.h2" +#line 4354 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7940,7 +7994,7 @@ auto i{0}; { auto i{0}; -#line 4362 "reflect.h2" +#line 4375 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -7965,7 +8019,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4385 "reflect.h2" +#line 4398 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -8026,7 +8080,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4445 "reflect.h2" +#line 4458 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -8051,75 +8105,75 @@ auto i{0}; { auto i{1}; -#line 4468 "reflect.h2" +#line 4481 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4473 "reflect.h2" +#line 4486 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4478 "reflect.h2" +#line 4491 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4482 "reflect.h2" +#line 4495 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4486 "reflect.h2" +#line 4499 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4490 "reflect.h2" +#line 4503 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4494 "reflect.h2" +#line 4507 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4498 "reflect.h2" +#line 4511 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4502 "reflect.h2" +#line 4515 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4506 "reflect.h2" +#line 4519 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4510 "reflect.h2" +#line 4523 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4514 "reflect.h2" +#line 4527 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4518 "reflect.h2" +#line 4531 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4522 "reflect.h2" +#line 4535 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8144,7 +8198,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4546 "reflect.h2" +#line 4559 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8183,7 +8237,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4585 "reflect.h2" +#line 4598 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -8202,18 +8256,18 @@ auto i{1}; } } -#line 4603 "reflect.h2" +#line 4616 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4607 "reflect.h2" +#line 4620 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4612 "reflect.h2" +#line 4625 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8222,7 +8276,7 @@ auto i{1}; { auto i{0}; -#line 4619 "reflect.h2" +#line 4632 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8236,7 +8290,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4631 "reflect.h2" +#line 4644 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8245,7 +8299,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4639 "reflect.h2" +#line 4652 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8278,26 +8332,26 @@ auto i{0}; }}}} } -#line 4680 "reflect.h2" +#line 4693 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4683 "reflect.h2" +#line 4696 "reflect.h2" } -#line 4685 "reflect.h2" +#line 4698 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4690 "reflect.h2" +#line 4703 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4695 "reflect.h2" +#line 4708 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8315,22 +8369,22 @@ auto i{0}; } } -#line 4713 "reflect.h2" +#line 4726 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4718 "reflect.h2" +#line 4731 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4723 "reflect.h2" +#line 4736 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4728 "reflect.h2" +#line 4741 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8338,7 +8392,7 @@ auto i{0}; diff += "}\n"; } -#line 4736 "reflect.h2" +#line 4749 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8354,7 +8408,7 @@ auto i{0}; } } -#line 4752 "reflect.h2" +#line 4765 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8401,7 +8455,7 @@ auto i{0}; }} } -#line 4799 "reflect.h2" +#line 4812 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8413,7 +8467,7 @@ auto i{0}; } } -#line 4810 "reflect.h2" +#line 4823 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8442,79 +8496,79 @@ auto i{0}; } } -#line 4838 "reflect.h2" +#line 4851 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4843 "reflect.h2" +#line 4856 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4847 "reflect.h2" +#line 4860 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4851 "reflect.h2" +#line 4864 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4855 "reflect.h2" +#line 4868 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4859 "reflect.h2" +#line 4872 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4863 "reflect.h2" +#line 4876 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4867 "reflect.h2" +#line 4880 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4871 "reflect.h2" +#line 4884 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4875 "reflect.h2" +#line 4888 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4879 "reflect.h2" +#line 4892 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4883 "reflect.h2" +#line 4896 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4887 "reflect.h2" +#line 4900 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4891 "reflect.h2" +#line 4904 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4896 "reflect.h2" +#line 4909 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8523,7 +8577,7 @@ auto i{0}; { auto i{0}; -#line 4903 "reflect.h2" +#line 4916 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8537,7 +8591,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4915 "reflect.h2" +#line 4928 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8548,86 +8602,58 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4925 "reflect.h2" +#line 4938 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4931 "reflect.h2" -auto autodiff(meta::type_declaration& t) -> void -{ - - std::string_view constexpr suffix_token{ "suffix=" }; - std::string_view constexpr order_token{ "order=" }; - - auto args {CPP2_UFCS(get_arguments)(t)}; - - std::string suffix {"_d"}; - int order {1}; - for ( auto const& arg_str : cpp2::move(args) ) { - if (CPP2_UFCS(starts_with)(arg_str, "\"") && CPP2_UFCS(ends_with)(arg_str, "\"")) { - auto arg {CPP2_UFCS(substr)(arg_str, 1, CPP2_UFCS(ssize)(arg_str) - 2)}; - - if (CPP2_UFCS(starts_with)(arg, suffix_token)) { - suffix = CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(suffix_token)); - continue; - } - if (CPP2_UFCS(starts_with)(arg, order_token)) { - if (!(string_util::string_to_int(CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(order_token)), order))) { - CPP2_UFCS(error)(t, "AD: Could not parse derivative order: " + cpp2::to_string(CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(order_token))) + ""); - return ; - } - continue; - } - } +#line 4952 "reflect.h2" + autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) + : simple_traverser{ } + , autodiff_handler_base{ ctx_ } + , decl{ decl_ }{ - CPP2_UFCS(error)(t, "AD: Unknown argument: " + cpp2::to_string(arg_str) + ""); - return ; +#line 4955 "reflect.h2" } - autodiff_context ad_ctx {}; - ad_ctx.suffix = suffix; - CPP2_UFCS(set_order)(ad_ctx, order); - - CPP2_UFCS(create_namespace_stack)(ad_ctx, t); - - for ( - auto const& m : CPP2_UFCS(get_members)(t) ) - if ( CPP2_UFCS(is_function)(m)) - { - auto mf {CPP2_UFCS(as_function)(m)}; +#line 4957 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ + base::traverse(decl); + } - CPP2_UFCS(enter_function)(ad_ctx); +#line 4962 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ + CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); - std::string diff {" " + cpp2::to_string(CPP2_UFCS(name)(mf)) + cpp2::to_string(suffix) + ": ("}; + diff = " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": ("; // 1. Generate the modified signature // a) Parameters - for ( auto const& param : CPP2_UFCS(get_parameters)(mf) ) { + for ( auto const& param : CPP2_UFCS(get_parameters)(f) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + ", "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + ", "; } diff += ") -> ("; // b) Returns - if (CPP2_UFCS(has_non_void_return_type)(mf) && CPP2_UFCS(empty)(CPP2_UFCS(get_returns)(mf))) {// TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + if (CPP2_UFCS(has_non_void_return_type)(f) && CPP2_UFCS(empty)(CPP2_UFCS(get_returns)(f))) {// TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) - if (CPP2_UFCS(has_deduced_return_type)(mf)) { + if (CPP2_UFCS(has_deduced_return_type)(f)) { // TODO: Take care of initialization order error. - diff += "r, r" + cpp2::to_string(suffix) + ", "; + diff += "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ", "; } else { - diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(mf)) + " = (), r" + cpp2::to_string(suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(get_unnamed_return_type)(mf))) + " = (), "; + diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "; } } else { - for ( auto const& param : CPP2_UFCS(get_returns)(mf) ) { + for ( auto const& param : CPP2_UFCS(get_returns)(f) ) { diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string(suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)(ad_ctx, CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + " = 0.0, "; + diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + " = 0.0, "; } } @@ -8635,16 +8661,16 @@ auto autodiff(meta::type_declaration& t) -> void // Generate the body - if (!(CPP2_UFCS(has_compound_body)(mf))) { - CPP2_UFCS(error)(mf, "temporary alpha limitation: a differentiable function must have a {}-enclosed body"); + if (!(CPP2_UFCS(has_compound_body)(f))) { + CPP2_UFCS(error)(f, "temporary alpha limitation: a differentiable function must have a {}-enclosed body"); return ; } -#line 5017 "reflect.h2" - autodiff_stmt_handler ad_impl {&ad_ctx, mf}; +#line 5006 "reflect.h2" + autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5020 "reflect.h2" - for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(mf)) ) +#line 5009 "reflect.h2" + for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); } @@ -8652,12 +8678,108 @@ auto autodiff(meta::type_declaration& t) -> void diff += "}"; - CPP2_UFCS(leave_function)(ad_ctx); + CPP2_UFCS(leave_function)((*cpp2::impl::assert_not_null(ctx))); + + CPP2_UFCS(add_member)(decl, diff); + diff = ""; + + CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); + } + +#line 5026 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ + CPP2_UFCS(error)(o, "AD: Do not know how to handle object_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(o)) + ""); + } + +#line 5031 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ + CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); + autodiff_declaration_handler ad {ctx, t}; + + for ( + auto const& m : CPP2_UFCS(get_members)(t) ) + if ( CPP2_UFCS(is_function)(m)) + { + CPP2_UFCS(pre_traverse)(ad, m); + } + + CPP2_UFCS(pop_stack)((*cpp2::impl::assert_not_null(ctx))); + } + +#line 5046 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ + CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); + } + +#line 5051 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ + CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); + } + +#line 5057 "reflect.h2" +auto autodiff(meta::type_declaration& t) -> void +{ + + std::string_view constexpr suffix_token{ "suffix=" }; + std::string_view constexpr order_token{ "order=" }; + + auto args {CPP2_UFCS(get_arguments)(t)}; + + std::string suffix {"_d"}; + int order {1}; + for ( auto const& arg_str : cpp2::move(args) ) { + if (CPP2_UFCS(starts_with)(arg_str, "\"") && CPP2_UFCS(ends_with)(arg_str, "\"")) { + auto arg {CPP2_UFCS(substr)(arg_str, 1, CPP2_UFCS(ssize)(arg_str) - 2)}; + + if (CPP2_UFCS(starts_with)(arg, suffix_token)) { + suffix = CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(suffix_token)); + continue; + } + if (CPP2_UFCS(starts_with)(arg, order_token)) { + if (!(string_util::string_to_int(CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(order_token)), order))) { + CPP2_UFCS(error)(t, "AD: Could not parse derivative order: " + cpp2::to_string(CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(order_token))) + ""); + return ; + } + continue; + } + } + + CPP2_UFCS(error)(t, "AD: Unknown argument: " + cpp2::to_string(arg_str) + ""); + return ; + } + + autodiff_context ad_ctx {}; + ad_ctx.suffix = cpp2::move(suffix); + CPP2_UFCS(set_order)(ad_ctx, order); - CPP2_UFCS(add_member)(t, cpp2::move(diff)); +#line 5093 "reflect.h2" + if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { + auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; + CPP2_UFCS(create_namespace_stack)(ad_ctx, p); + autodiff_declaration_handler ad {&ad_ctx, cpp2::move(p)}; + CPP2_UFCS(pre_traverse)(cpp2::move(ad), t); - CPP2_UFCS(add_as_differentiated)(ad_ctx, cpp2::move(mf)); } + else {if (CPP2_UFCS(parent_is_type)(t)) { + auto p {CPP2_UFCS(as_type)(CPP2_UFCS(get_parent)(t))}; + CPP2_UFCS(create_namespace_stack)(ad_ctx, p); + autodiff_declaration_handler ad {&ad_ctx, cpp2::move(p)}; + CPP2_UFCS(pre_traverse)(cpp2::move(ad), t); + } + else { + // TODO: Remove when global namespace is available. + // Traverse without parent context + CPP2_UFCS(push_stack)(ad_ctx, t); + autodiff_declaration_handler ad {&ad_ctx, t}; + + for ( + auto const& m : CPP2_UFCS(get_members)(t) ) + if ( CPP2_UFCS(is_function)(m)) + { + CPP2_UFCS(pre_traverse)(ad, m); + } + CPP2_UFCS(pop_stack)(ad_ctx); + }} if (1 != cpp2::move(order)) { CPP2_UFCS(add_runtime_support_include)(t, "cpp2taylor.h"); @@ -8759,7 +8881,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5045 "reflect.h2" +#line 5131 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8775,11 +8897,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5061 "reflect.h2" +#line 5147 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5065 "reflect.h2" +#line 5151 "reflect.h2" // mod: i // mod: m // mod: s @@ -8787,116 +8909,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5074 "reflect.h2" +#line 5160 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5083 "reflect.h2" +#line 5169 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5085 "reflect.h2" +#line 5171 "reflect.h2" } -#line 5087 "reflect.h2" +#line 5173 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5089 "reflect.h2" +#line 5175 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5095 "reflect.h2" +#line 5181 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5096 "reflect.h2" +#line 5182 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5097 "reflect.h2" +#line 5183 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5112 "reflect.h2" +#line 5198 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5115 "reflect.h2" +#line 5201 "reflect.h2" } -#line 5117 "reflect.h2" +#line 5203 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5121 "reflect.h2" +#line 5207 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5133 "reflect.h2" +#line 5219 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5136 "reflect.h2" +#line 5222 "reflect.h2" } -#line 5138 "reflect.h2" +#line 5224 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5142 "reflect.h2" +#line 5228 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5152 "reflect.h2" +#line 5238 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5154 "reflect.h2" +#line 5240 "reflect.h2" } -#line 5156 "reflect.h2" +#line 5242 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5160 "reflect.h2" +#line 5246 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5172 "reflect.h2" +#line 5258 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5175 "reflect.h2" +#line 5261 "reflect.h2" } -#line 5177 "reflect.h2" +#line 5263 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5183 "reflect.h2" +#line 5269 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5189 "reflect.h2" +#line 5275 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -8905,7 +9027,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5197 "reflect.h2" +#line 5283 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -8921,7 +9043,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5225 "reflect.h2" +#line 5311 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -8929,14 +9051,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5233 "reflect.h2" +#line 5319 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5240 "reflect.h2" +#line 5326 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -8948,15 +9070,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5252 "reflect.h2" +#line 5338 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5257 "reflect.h2" +#line 5343 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5261 "reflect.h2" +#line 5347 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -8977,7 +9099,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5287 "reflect.h2" +#line 5373 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -8986,20 +9108,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5296 "reflect.h2" +#line 5382 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5302 "reflect.h2" +#line 5388 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5309 "reflect.h2" +#line 5395 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9014,16 +9136,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5339 "reflect.h2" +#line 5425 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5343 "reflect.h2" +#line 5429 "reflect.h2" } -#line 5349 "reflect.h2" +#line 5435 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9033,7 +9155,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5359 "reflect.h2" +#line 5445 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9041,17 +9163,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5366 "reflect.h2" +#line 5452 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5370 "reflect.h2" +#line 5456 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5377 "reflect.h2" +#line 5463 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9061,7 +9183,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5386 "reflect.h2" +#line 5472 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9069,24 +9191,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5393 "reflect.h2" +#line 5479 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5401 "reflect.h2" +#line 5487 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5405 "reflect.h2" +#line 5491 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5409 "reflect.h2" +#line 5495 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9098,22 +9220,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5420 "reflect.h2" +#line 5506 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5426 "reflect.h2" +#line 5512 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5430 "reflect.h2" +#line 5516 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5434 "reflect.h2" +#line 5520 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9121,7 +9243,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5441 "reflect.h2" +#line 5527 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9133,10 +9255,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5454 "reflect.h2" +#line 5540 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5457 "reflect.h2" +#line 5543 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9176,7 +9298,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5497 "reflect.h2" +#line 5583 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9188,14 +9310,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5508 "reflect.h2" +#line 5594 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5509 "reflect.h2" +#line 5595 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5510 "reflect.h2" +#line 5596 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5512 "reflect.h2" +#line 5598 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9205,10 +9327,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5521 "reflect.h2" +#line 5607 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5523 "reflect.h2" +#line 5609 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9230,14 +9352,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5544 "reflect.h2" +#line 5630 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5545 "reflect.h2" +#line 5631 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5546 "reflect.h2" +#line 5632 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5548 "reflect.h2" +#line 5634 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9251,7 +9373,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5561 "reflect.h2" +#line 5647 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9273,7 +9395,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5582 "reflect.h2" +#line 5668 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9284,12 +9406,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5592 "reflect.h2" +#line 5678 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5593 "reflect.h2" +#line 5679 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5598 "reflect.h2" +#line 5684 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9344,7 +9466,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5652 "reflect.h2" +#line 5738 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9384,7 +9506,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5691 "reflect.h2" +#line 5777 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9400,21 +9522,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5708 "reflect.h2" +#line 5794 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5709 "reflect.h2" +#line 5795 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5710 "reflect.h2" +#line 5796 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5712 "reflect.h2" +#line 5798 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5727 "reflect.h2" +#line 5813 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9422,7 +9544,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5734 "reflect.h2" +#line 5820 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9432,22 +9554,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5752 "reflect.h2" +#line 5838 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5757 "reflect.h2" +#line 5843 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5763 "reflect.h2" +#line 5849 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5769 "reflect.h2" +#line 5855 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9456,7 +9578,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5777 "reflect.h2" +#line 5863 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9468,7 +9590,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5788 "reflect.h2" +#line 5874 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9476,7 +9598,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5795 "reflect.h2" +#line 5881 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9497,7 +9619,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5816 "reflect.h2" +#line 5902 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9507,7 +9629,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5826 "reflect.h2" +#line 5912 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9530,33 +9652,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5850 "reflect.h2" +#line 5936 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5856 "reflect.h2" +#line 5942 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5860 "reflect.h2" +#line 5946 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5866 "reflect.h2" +#line 5952 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5874 "reflect.h2" +#line 5960 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9565,7 +9687,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5882 "reflect.h2" +#line 5968 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9574,22 +9696,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5892 "reflect.h2" +#line 5978 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5896 "reflect.h2" +#line 5982 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5900 "reflect.h2" +#line 5986 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5904 "reflect.h2" +#line 5990 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9613,18 +9735,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 5929 "reflect.h2" +#line 6015 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 5944 "reflect.h2" +#line 6030 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 5946 "reflect.h2" +#line 6032 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9635,15 +9757,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 5961 "reflect.h2" +#line 6047 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 5964 "reflect.h2" +#line 6050 "reflect.h2" } -#line 5966 "reflect.h2" +#line 6052 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9661,7 +9783,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 5983 "reflect.h2" +#line 6069 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9669,7 +9791,7 @@ generation_function_context::generation_function_context(){} } } -#line 5990 "reflect.h2" +#line 6076 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9683,7 +9805,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6003 "reflect.h2" +#line 6089 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9699,14 +9821,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6024 "reflect.h2" +#line 6110 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6026 "reflect.h2" +#line 6112 "reflect.h2" } -#line 6028 "reflect.h2" +#line 6114 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9715,11 +9837,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6043 "reflect.h2" +#line 6129 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6045 "reflect.h2" +#line 6131 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9727,7 +9849,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6052 "reflect.h2" +#line 6138 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9736,37 +9858,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6060 "reflect.h2" +#line 6146 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6074 "reflect.h2" +#line 6160 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6078 "reflect.h2" +#line 6164 "reflect.h2" } -#line 6080 "reflect.h2" +#line 6166 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6084 "reflect.h2" +#line 6170 "reflect.h2" } -#line 6086 "reflect.h2" +#line 6172 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6090 "reflect.h2" +#line 6176 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9775,14 +9897,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6096 "reflect.h2" +#line 6182 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6101 "reflect.h2" +#line 6187 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9795,7 +9917,7 @@ size_t i{0}; } } -#line 6113 "reflect.h2" +#line 6199 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9817,7 +9939,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6134 "reflect.h2" +#line 6220 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9836,7 +9958,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6152 "reflect.h2" +#line 6238 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9852,14 +9974,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6167 "reflect.h2" +#line 6253 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6173 "reflect.h2" +#line 6259 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9867,19 +9989,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6190 "reflect.h2" +#line 6276 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6191 "reflect.h2" +#line 6277 "reflect.h2" { -#line 6196 "reflect.h2" +#line 6282 "reflect.h2" } -#line 6199 "reflect.h2" +#line 6285 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10005,7 +10127,7 @@ size_t i{0}; ); } -#line 6324 "reflect.h2" +#line 6410 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10015,13 +10137,13 @@ size_t i{0}; ); } -#line 6333 "reflect.h2" +#line 6419 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6338 "reflect.h2" +#line 6424 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10032,12 +10154,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6350 "reflect.h2" +#line 6436 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6355 "reflect.h2" +#line 6441 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10071,7 +10193,7 @@ size_t i{0}; } -#line 6391 "reflect.h2" +#line 6477 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10080,19 +10202,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6414 "reflect.h2" +#line 6500 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6415 "reflect.h2" +#line 6501 "reflect.h2" { -#line 6420 "reflect.h2" +#line 6506 "reflect.h2" } -#line 6422 "reflect.h2" +#line 6508 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10194,19 +10316,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6523 "reflect.h2" +#line 6609 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6527 "reflect.h2" +#line 6613 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6551 "reflect.h2" +#line 6637 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10225,7 +10347,7 @@ size_t i{0}; return r; } -#line 6569 "reflect.h2" +#line 6655 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10240,7 +10362,7 @@ size_t i{0}; return r; } -#line 6583 "reflect.h2" +#line 6669 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10400,7 +10522,7 @@ size_t i{0}; } } -#line 6742 "reflect.h2" +#line 6828 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10409,7 +10531,7 @@ size_t i{0}; return r; } -#line 6750 "reflect.h2" +#line 6836 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10428,7 +10550,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6768 "reflect.h2" +#line 6854 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10460,7 +10582,7 @@ size_t i{0}; } } -#line 6799 "reflect.h2" +#line 6885 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10471,7 +10593,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6811 "reflect.h2" +#line 6897 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10510,7 +10632,7 @@ size_t i{0}; return r; } -#line 6852 "reflect.h2" +#line 6938 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10528,7 +10650,7 @@ size_t i{0}; }} } -#line 6872 "reflect.h2" +#line 6958 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10542,16 +10664,16 @@ size_t i{0}; } } -#line 6898 "reflect.h2" +#line 6984 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6901 "reflect.h2" +#line 6987 "reflect.h2" } -#line 6903 "reflect.h2" +#line 6989 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10563,7 +10685,7 @@ size_t i{0}; } } -#line 6914 "reflect.h2" +#line 7000 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10571,14 +10693,14 @@ size_t i{0}; return r; } -#line 6921 "reflect.h2" +#line 7007 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 6929 "reflect.h2" +#line 7015 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10604,7 +10726,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 6957 "reflect.h2" +#line 7043 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10630,11 +10752,11 @@ size_t i{0}; return r; } -#line 6994 "reflect.h2" +#line 7080 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 6996 "reflect.h2" +#line 7082 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10708,7 +10830,7 @@ size_t i{0}; return nullptr; } -#line 7069 "reflect.h2" +#line 7155 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10721,7 +10843,7 @@ size_t i{0}; }} } -#line 7081 "reflect.h2" +#line 7167 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10735,7 +10857,7 @@ size_t i{0}; }} } -#line 7094 "reflect.h2" +#line 7180 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10755,7 +10877,7 @@ size_t i{0}; return r; } -#line 7113 "reflect.h2" +#line 7199 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10766,7 +10888,7 @@ size_t i{0}; return r; } -#line 7123 "reflect.h2" +#line 7209 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10778,14 +10900,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7134 "reflect.h2" +#line 7220 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7146 "reflect.h2" +#line 7232 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10809,7 +10931,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7170 "reflect.h2" +#line 7256 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10819,7 +10941,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7182 "reflect.h2" +#line 7268 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10835,7 +10957,7 @@ size_t i{0}; } } -#line 7202 "reflect.h2" +#line 7288 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10853,15 +10975,15 @@ size_t i{0}; }} } -#line 7238 "reflect.h2" +#line 7324 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7241 "reflect.h2" +#line 7327 "reflect.h2" } -#line 7243 "reflect.h2" +#line 7329 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -10897,7 +11019,7 @@ size_t i{0}; return source; } -#line 7278 "reflect.h2" +#line 7364 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -10913,7 +11035,7 @@ size_t i{0}; } } -#line 7294 "reflect.h2" +#line 7380 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -10922,7 +11044,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -10977,7 +11099,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7363 "reflect.h2" +#line 7449 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11099,7 +11221,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7485 "reflect.h2" +#line 7571 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index b13eae503..63f899374 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4195,6 +4195,19 @@ autodiff_context: type = { leave_function: (inout this) = { } + push_stack: (inout this, decl: meta::type_or_namespace_declaration) = { + full_name: std::string = ""; + + if !declaration_stack.empty() { + full_name += declaration_stack.back().full_name; + } + + full_name += "::"; + full_name += decl.name(); + + declaration_stack.push_back(autodiff_declaration_stack_item(full_name, decl)); + } + pop_stack: (inout this) = { assert(!declaration_stack.empty()); @@ -4928,79 +4941,55 @@ autodiff_stmt_handler: type = { } } -autodiff: (inout t: meta::type_declaration) = -{ - - suffix_token : std::string_view == "suffix="; - order_token : std::string_view == "order="; +autodiff_declaration_handler: type = { + this: simple_traverser = (); + this: autodiff_handler_base; - args := t.get_arguments(); + base: type == simple_traverser; - suffix : std::string = "_d"; - order : int = 1; - for args do (arg_str) { - if arg_str.starts_with("\"") && arg_str.ends_with("\"") { - arg := arg_str.substr(1, arg_str.ssize() - 2); + decl: meta::type_or_namespace_declaration; - if arg.starts_with(suffix_token) { - suffix = arg.substr(suffix_token.size()); - continue; - } - if arg.starts_with(order_token) { - if !string_util::string_to_int(arg.substr(order_token.size()), order) { - t.error("AD: Could not parse derivative order: (arg.substr(order_token.size()))$"); - return; - } - continue; - } - } - - t.error("AD: Unknown argument: (arg_str)$"); - return; + operator=: (out this, ctx_: *autodiff_context, decl_: meta::type_or_namespace_declaration) = { + autodiff_handler_base = (ctx_); + decl = decl_; } - ad_ctx: autodiff_context = (); - ad_ctx.suffix = suffix; - ad_ctx.set_order(order); + traverse: (override inout this, decl: meta::declaration) = { + base::traverse(decl); + } - ad_ctx.create_namespace_stack(t); - for t.get_members() - do (m) - if m.is_function() - { - mf := m.as_function(); - - ad_ctx.enter_function(); + traverse: (override inout this, f: meta::function_declaration) = { + ctx*.enter_function(); - diff: std::string = " (mf.name())$(suffix)$: ("; + diff = " (f.name())$(ctx*.suffix)$: ("; // 1. Generate the modified signature // a) Parameters - for mf.get_parameters() do (param) { + for f.get_parameters() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$, "; - diff += "(param.get_declaration().name())$(suffix)$ : (ad_ctx.get_ad_type(param.get_declaration().type()))$, "; + diff += "(param.get_declaration().name())$(ctx*.suffix)$ : (ctx*.get_ad_type(param.get_declaration().type()))$, "; } diff += ") -> ("; // b) Returns - if mf.has_non_void_return_type() && mf.get_returns().empty() { // TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + if f.has_non_void_return_type() && f.get_returns().empty() { // TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) - if mf.has_deduced_return_type() { + if f.has_deduced_return_type() { // TODO: Take care of initialization order error. - diff += "r, r(suffix)$, "; + diff += "r, r(ctx*.suffix)$, "; } else { - diff += "r: (mf.get_unnamed_return_type())$ = (), r(suffix)$: (ad_ctx.get_ad_type(mf.get_unnamed_return_type()))$ = (), "; + diff += "r: (f.get_unnamed_return_type())$ = (), r(ctx*.suffix)$: (ctx*.get_ad_type(f.get_unnamed_return_type()))$ = (), "; } } else { - for mf.get_returns() do (param) { + for f.get_returns() do (param) { diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(param.get_declaration().name())$(suffix)$ : (ad_ctx.get_ad_type(param.get_declaration().type()))$ = 0.0, "; + diff += "(param.get_declaration().name())$(ctx*.suffix)$ : (ctx*.get_ad_type(param.get_declaration().type()))$ = 0.0, "; } } @@ -5008,16 +4997,16 @@ autodiff: (inout t: meta::type_declaration) = // Generate the body - if !mf.has_compound_body() { - mf.error( "temporary alpha limitation: a differentiable function must have a {}-enclosed body" ); + if !f.has_compound_body() { + f.error( "temporary alpha limitation: a differentiable function must have a {}-enclosed body" ); return; } - ad_impl : autodiff_stmt_handler = (ad_ctx&, mf); + ad_impl : autodiff_stmt_handler = (ctx*&, f); - for mf.get_compound_body().get_statements() do (stmt) + for f.get_compound_body().get_statements() do (stmt) { ad_impl..pre_traverse(stmt); } @@ -5025,11 +5014,108 @@ autodiff: (inout t: meta::type_declaration) = diff += "}"; - ad_ctx.leave_function(); + ctx*.leave_function(); + + decl.add_member( diff ); + diff = ""; + + ctx*.add_as_differentiated(f); + } + + + traverse: (override inout this, o: meta::object_declaration) = { + o.error("AD: Do not know how to handle object_declaration: (o.to_string())$"); + } + - t.add_member( diff ); + traverse: (override inout this, t: meta::type_declaration) = { + ctx*.push_stack(t); + ad: autodiff_declaration_handler = (ctx, t); + + for t.get_members() + do (m) + if m.is_function() + { + ad.pre_traverse(m); + } + + ctx*.pop_stack(); + } + + + traverse: (override inout this, t: meta::parameter_declaration) = { + t.error("AD: Do not know how to handle parameter_declaration: (t.to_string())$"); + } + + + traverse: (override inout this, stmt: meta::statement) = { + stmt.error("AD: Do not know how to handle statement in declaration context: (stmt.to_string())$"); + } +} + + +autodiff: (inout t: meta::type_declaration) = +{ + + suffix_token : std::string_view == "suffix="; + order_token : std::string_view == "order="; - ad_ctx.add_as_differentiated(mf); + args := t.get_arguments(); + + suffix : std::string = "_d"; + order : int = 1; + for args do (arg_str) { + if arg_str.starts_with("\"") && arg_str.ends_with("\"") { + arg := arg_str.substr(1, arg_str.ssize() - 2); + + if arg.starts_with(suffix_token) { + suffix = arg.substr(suffix_token.size()); + continue; + } + if arg.starts_with(order_token) { + if !string_util::string_to_int(arg.substr(order_token.size()), order) { + t.error("AD: Could not parse derivative order: (arg.substr(order_token.size()))$"); + return; + } + continue; + } + } + + t.error("AD: Unknown argument: (arg_str)$"); + return; + } + + ad_ctx: autodiff_context = (); + ad_ctx.suffix = suffix; + ad_ctx.set_order(order); + + + if t.parent_is_nonglobal_namespace() { + p := t.get_parent().as_nonglobal_namespace(); + ad_ctx.create_namespace_stack(p); + ad: autodiff_declaration_handler = (ad_ctx&, p); + ad.pre_traverse(t); + + } + else if t.parent_is_type() { + p := t.get_parent().as_type(); + ad_ctx.create_namespace_stack(p); + ad: autodiff_declaration_handler = (ad_ctx&, p); + ad.pre_traverse(t); + } + else { + // TODO: Remove when global namespace is available. + // Traverse without parent context + ad_ctx.push_stack(t); + ad: autodiff_declaration_handler = (ad_ctx&, t); + + for t.get_members() + do (m) + if m.is_function() + { + ad.pre_traverse(m); + } + ad_ctx.pop_stack(); } if 1 != order { From e83e561fc558222dacaab4e67a1b36ddcfe7e45d Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 15 Aug 2025 13:53:38 +0200 Subject: [PATCH 30/54] Added handling for differentiation of symbols outside of metafunction type declaration. --- regression-tests/pure2-autodiff.cpp2 | 9 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 230 +- .../test-results/pure2-autodiff.cpp2.output | 27 + source/parse.h | 30 + source/reflect.h | 2577 +++++++++-------- source/reflect.h2 | 17 +- 7 files changed, 1513 insertions(+), 1378 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 6adc88238..300c4591b 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -1,5 +1,9 @@ ad_name: namespace = { +func_outer: (x: double, y: double) -> (ret: double) = { + ret = x + y; +} + ad_test: @autodiff @print type = { add_1: (x: double, y: double) -> (r: double) = { @@ -58,6 +62,10 @@ ad_test: @autodiff @print type = { r = x * func(x, y); } + func_outer_call: (x: double, y: double) -> (r: double) = { + r = x * func_outer(x, y); + } + sin_call: (x: double, y: double) -> (r: double) = { r = sin(x - y); } @@ -184,6 +192,7 @@ main: () = { write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 278b7af31..cdd65c3e1 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -11,6 +11,7 @@ diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 91d7ddff4..82253538c 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -9,10 +9,10 @@ #line 1 "pure2-autodiff.cpp2" namespace ad_name { -#line 3 "pure2-autodiff.cpp2" +#line 7 "pure2-autodiff.cpp2" class ad_test; -#line 155 "pure2-autodiff.cpp2" +#line 163 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -22,136 +22,151 @@ class ad_test_twice; #line 1 "pure2-autodiff.cpp2" namespace ad_name { +using func_outer_ret = double; + #line 3 "pure2-autodiff.cpp2" +[[nodiscard]] auto func_outer(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_ret; +struct func_outer_d_ret { double ret; double ret_d; }; + + +[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret; + + +#line 7 "pure2-autodiff.cpp2" class ad_test { using add_1_ret = double; -#line 5 "pure2-autodiff.cpp2" +#line 9 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 9 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; +using func_outer_call_ret = double; + + +#line 65 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 61 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 65 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 73 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 82 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 86 "pure2-autodiff.cpp2" +#line 94 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 92 "pure2-autodiff.cpp2" +#line 100 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 100 "pure2-autodiff.cpp2" +#line 108 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 107 "pure2-autodiff.cpp2" +#line 115 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 114 "pure2-autodiff.cpp2" +#line 122 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 121 "pure2-autodiff.cpp2" +#line 129 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 130 "pure2-autodiff.cpp2" +#line 138 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 141 "pure2-autodiff.cpp2" +#line 149 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; struct add_1_d_ret { double r; double r_d; }; @@ -210,6 +225,10 @@ struct func_call_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret; +struct func_outer_call_d_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto func_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_call_d_ret; + struct sin_call_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret; @@ -263,14 +282,14 @@ public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test const&) -> void = delete; -#line 154 "pure2-autodiff.cpp2" +#line 162 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 158 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -290,12 +309,12 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 161 "pure2-autodiff.cpp2" +#line 169 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 167 "pure2-autodiff.cpp2" +#line 175 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -303,115 +322,136 @@ auto main() -> int; #line 1 "pure2-autodiff.cpp2" namespace ad_name { -#line 5 "pure2-autodiff.cpp2" +#line 3 "pure2-autodiff.cpp2" +[[nodiscard]] auto func_outer(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_ret{ + cpp2::impl::deferred_init ret; +#line 4 "pure2-autodiff.cpp2" + ret.construct(x + y); +return std::move(ret.value()); } + +[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret{ + double ret {0.0}; + double ret_d {0.0};ret_d = x_d + y_d; +ret = x + y; +return { std::move(ret), std::move(ret_d) }; +} + +#line 9 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 6 "pure2-autodiff.cpp2" +#line 10 "pure2-autodiff.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 9 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 10 "pure2-autodiff.cpp2" +#line 14 "pure2-autodiff.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 14 "pure2-autodiff.cpp2" +#line 18 "pure2-autodiff.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 18 "pure2-autodiff.cpp2" +#line 22 "pure2-autodiff.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 22 "pure2-autodiff.cpp2" +#line 26 "pure2-autodiff.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 26 "pure2-autodiff.cpp2" +#line 30 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 30 "pure2-autodiff.cpp2" +#line 34 "pure2-autodiff.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 34 "pure2-autodiff.cpp2" +#line 38 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 38 "pure2-autodiff.cpp2" +#line 42 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 42 "pure2-autodiff.cpp2" +#line 46 "pure2-autodiff.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 46 "pure2-autodiff.cpp2" +#line 50 "pure2-autodiff.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 50 "pure2-autodiff.cpp2" +#line 54 "pure2-autodiff.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 54 "pure2-autodiff.cpp2" +#line 58 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 58 "pure2-autodiff.cpp2" +#line 62 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 61 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ + cpp2::impl::deferred_init r; +#line 66 "pure2-autodiff.cpp2" + r.construct(x * func_outer(x, y)); + return std::move(r.value()); } + +#line 69 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 62 "pure2-autodiff.cpp2" +#line 70 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 65 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 66 "pure2-autodiff.cpp2" +#line 74 "pure2-autodiff.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -419,10 +459,10 @@ namespace ad_name { }return std::move(r.value()); } -#line 73 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 74 "pure2-autodiff.cpp2" +#line 82 "pure2-autodiff.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -431,24 +471,24 @@ namespace ad_name { }return std::move(r.value()); } -#line 82 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 86 "pure2-autodiff.cpp2" +#line 94 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 87 "pure2-autodiff.cpp2" +#line 95 "pure2-autodiff.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 92 "pure2-autodiff.cpp2" +#line 100 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 93 "pure2-autodiff.cpp2" +#line 101 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -456,40 +496,40 @@ namespace ad_name { static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 100 "pure2-autodiff.cpp2" +#line 108 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 101 "pure2-autodiff.cpp2" +#line 109 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 107 "pure2-autodiff.cpp2" +#line 115 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 108 "pure2-autodiff.cpp2" +#line 116 "pure2-autodiff.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 114 "pure2-autodiff.cpp2" +#line 122 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 115 "pure2-autodiff.cpp2" +#line 123 "pure2-autodiff.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 121 "pure2-autodiff.cpp2" +#line 129 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 122 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -498,10 +538,10 @@ namespace ad_name { }return std::move(r.value()); } -#line 130 "pure2-autodiff.cpp2" +#line 138 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 131 "pure2-autodiff.cpp2" +#line 139 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -512,10 +552,10 @@ namespace ad_name { cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 141 "pure2-autodiff.cpp2" +#line 149 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 142 "pure2-autodiff.cpp2" +#line 150 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -647,6 +687,19 @@ auto temp_2 {func_d(x, x_d, y, y_d)}; return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto ad_test::func_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_call_d_ret{ + double r {0.0}; + double r_d {0.0}; +auto temp_2 {func_outer_d(x, x_d, y, y_d)}; + + auto temp_1 {temp_2.ret}; + + auto temp_1_d {cpp2::move(temp_2).ret_d}; + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; + r = x * cpp2::move(temp_1); + return { std::move(r), std::move(r_d) }; + } + [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret{ double r {0.0}; double r_d {0.0}; @@ -818,13 +871,13 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 155 "pure2-autodiff.cpp2" +#line 163 "pure2-autodiff.cpp2" } -#line 158 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 159 "pure2-autodiff.cpp2" +#line 167 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -861,12 +914,12 @@ auto temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 163 "pure2-autodiff.cpp2" +#line 171 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 167 "pure2-autodiff.cpp2" +#line 175 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -887,6 +940,7 @@ auto main() -> int{ write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index b3a384df4..72ce41812 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -128,6 +128,15 @@ ad_test:/* @autodiff @print */ type = return; } + func_outer_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func_outer(x, y); + return; + } + sin_call:( in x: double, in y: double, @@ -500,6 +509,24 @@ ad_test:/* @autodiff @print */ type = return; } + func_outer_call_d:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_2: _ = func_outer_d(x, x_d, y, y_d); + temp_1: _ = temp_2.ret; + temp_1_d: _ = temp_2.ret_d; + r_d = x * temp_1_d + temp_1 * x_d; + r = x * temp_1; + return; + } + sin_call_d:( in x: double, in x_d: double, diff --git a/source/parse.h b/source/parse.h index 3227ef35a..02f906dca 100644 --- a/source/parse.h +++ b/source/parse.h @@ -4073,6 +4073,36 @@ struct declaration_node return true; } + auto add_namespace_member( std::unique_ptr&& statement ) + -> bool + { + if ( + !is_namespace() + || !initializer + || !initializer->is_compound() + || !statement->is_declaration() + ) + { + return false; + } + + // Tell this declaration statement that we are its new parent + // and check to ensure that it doesn't already have a parent + // (that shouldn't happen because we should only get here for a + // generated statement that hasn't been added elsewhere yet) + auto decl = statement->get_if(); + assert( + decl + && !decl->parent_declaration + ); + decl->parent_declaration = this; + + // And actually adopt it into our list of statements + auto compound_stmt = initializer->get_if(); + assert (compound_stmt); + compound_stmt->statements.push_back(std::move(statement)); + return true; + } auto add_function_initializer( std::unique_ptr&& statement ) -> bool diff --git a/source/reflect.h b/source/reflect.h index 978d46f19..74b28eff0 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -36,173 +36,173 @@ class object_declaration; #line 451 "reflect.h2" class type_or_namespace_declaration; -#line 561 "reflect.h2" +#line 570 "reflect.h2" class type_declaration; -#line 604 "reflect.h2" +#line 613 "reflect.h2" class namespace_declaration; -#line 623 "reflect.h2" +#line 632 "reflect.h2" class alias_declaration; -#line 642 "reflect.h2" +#line 651 "reflect.h2" class parameter_declaration; -#line 688 "reflect.h2" +#line 697 "reflect.h2" template class binary_expression; -#line 815 "reflect.h2" +#line 824 "reflect.h2" class expression_list; -#line 848 "reflect.h2" +#line 857 "reflect.h2" class prefix_expression; -#line 890 "reflect.h2" +#line 899 "reflect.h2" class postfix_expression; -#line 961 "reflect.h2" +#line 970 "reflect.h2" class template_arg; -#line 987 "reflect.h2" +#line 996 "reflect.h2" class unqualified_id; -#line 1019 "reflect.h2" +#line 1028 "reflect.h2" class qualified_id; -#line 1063 "reflect.h2" +#line 1072 "reflect.h2" class type_id; -#line 1106 "reflect.h2" +#line 1115 "reflect.h2" class primary_expression; -#line 1145 "reflect.h2" +#line 1154 "reflect.h2" class id_expression; -#line 1181 "reflect.h2" +#line 1190 "reflect.h2" class expression; -#line 1232 "reflect.h2" +#line 1241 "reflect.h2" class is_as_expression; -#line 1293 "reflect.h2" +#line 1302 "reflect.h2" class statement; -#line 1335 "reflect.h2" +#line 1344 "reflect.h2" class expression_statement; -#line 1357 "reflect.h2" +#line 1366 "reflect.h2" class compound_statement; -#line 1396 "reflect.h2" +#line 1405 "reflect.h2" class selection_statement; -#line 1422 "reflect.h2" +#line 1431 "reflect.h2" class return_statement; -#line 1444 "reflect.h2" +#line 1453 "reflect.h2" class iteration_statement; -#line 1941 "reflect.h2" +#line 1950 "reflect.h2" class value_member_info; -#line 2475 "reflect.h2" +#line 2484 "reflect.h2" class simple_traverser; -#line 3957 "reflect.h2" +#line 3966 "reflect.h2" class autodiff_special_func; -#line 3986 "reflect.h2" +#line 3995 "reflect.h2" class autodiff_declaration_stack_item; -#line 4009 "reflect.h2" +#line 4018 "reflect.h2" class autodiff_context; -#line 4235 "reflect.h2" +#line 4242 "reflect.h2" class autodiff_handler_base; -#line 4249 "reflect.h2" +#line 4256 "reflect.h2" class autodiff_expression_handler; -#line 4685 "reflect.h2" +#line 4692 "reflect.h2" class autodiff_stmt_handler; -#line 4944 "reflect.h2" +#line 4951 "reflect.h2" class autodiff_declaration_handler; -#line 5149 "reflect.h2" +#line 5156 "reflect.h2" class expression_flags; -#line 5165 "reflect.h2" +#line 5172 "reflect.h2" class regex_token; -#line 5192 "reflect.h2" +#line 5199 "reflect.h2" class regex_token_check; -#line 5213 "reflect.h2" +#line 5220 "reflect.h2" class regex_token_code; -#line 5234 "reflect.h2" +#line 5241 "reflect.h2" class regex_token_empty; -#line 5252 "reflect.h2" +#line 5259 "reflect.h2" class regex_token_list; -#line 5304 "reflect.h2" +#line 5311 "reflect.h2" class parse_context_group_state; -#line 5365 "reflect.h2" +#line 5372 "reflect.h2" class parse_context_branch_reset_state; -#line 5408 "reflect.h2" +#line 5415 "reflect.h2" class parse_context; -#line 5809 "reflect.h2" +#line 5816 "reflect.h2" class generation_function_context; -#line 5827 "reflect.h2" +#line 5834 "reflect.h2" class generation_context; -#line 6026 "reflect.h2" +#line 6033 "reflect.h2" class alternative_token; -#line 6041 "reflect.h2" +#line 6048 "reflect.h2" class alternative_token_gen; -#line 6106 "reflect.h2" +#line 6113 "reflect.h2" class any_token; -#line 6123 "reflect.h2" +#line 6130 "reflect.h2" class atomic_group_token; -#line 6153 "reflect.h2" +#line 6160 "reflect.h2" class char_token; -#line 6268 "reflect.h2" +#line 6275 "reflect.h2" class class_token; -#line 6492 "reflect.h2" +#line 6499 "reflect.h2" class group_ref_token; -#line 6629 "reflect.h2" +#line 6636 "reflect.h2" class group_token; -#line 6976 "reflect.h2" +#line 6983 "reflect.h2" class lookahead_lookbehind_token; -#line 7071 "reflect.h2" +#line 7078 "reflect.h2" class range_token; -#line 7228 "reflect.h2" +#line 7235 "reflect.h2" class special_range_token; -#line 7314 "reflect.h2" +#line 7321 "reflect.h2" template class regex_generator; -#line 7571 "reflect.h2" +#line 7578 "reflect.h2" } } @@ -549,21 +549,21 @@ class type_or_namespace_declaration public: type_or_namespace_declaration(type_or_namespace_declaration&& that) noexcept; -#line 558 "reflect.h2" +#line 567 "reflect.h2" }; -#line 561 "reflect.h2" +#line 570 "reflect.h2" class type_declaration : public type_or_namespace_declaration { -#line 565 "reflect.h2" +#line 574 "reflect.h2" public: type_declaration( declaration_node* n_, cpp2::impl::in s ); -#line 576 "reflect.h2" +#line 585 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; @@ -571,26 +571,26 @@ struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_ -#line 580 "reflect.h2" +#line 589 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 596 "reflect.h2" +#line 605 "reflect.h2" public: [[nodiscard]] auto disable_member_function_generation() & -> decltype(auto); -#line 599 "reflect.h2" +#line 608 "reflect.h2" public: [[nodiscard]] auto remove_marked_members() & -> decltype(auto); public: [[nodiscard]] auto remove_all_members() & -> decltype(auto); public: type_declaration(type_declaration const& that); public: type_declaration(type_declaration&& that) noexcept; -#line 601 "reflect.h2" +#line 610 "reflect.h2" }; -#line 604 "reflect.h2" +#line 613 "reflect.h2" class namespace_declaration : public type_or_namespace_declaration { -#line 608 "reflect.h2" +#line 617 "reflect.h2" public: namespace_declaration( declaration_node* n_, @@ -600,14 +600,14 @@ class namespace_declaration public: namespace_declaration(namespace_declaration&& that) noexcept; -#line 617 "reflect.h2" +#line 626 "reflect.h2" }; -#line 623 "reflect.h2" +#line 632 "reflect.h2" class alias_declaration : public declaration { -#line 627 "reflect.h2" +#line 636 "reflect.h2" public: alias_declaration( declaration_node* n_, @@ -617,21 +617,21 @@ class alias_declaration public: alias_declaration(alias_declaration&& that) noexcept; -#line 636 "reflect.h2" +#line 645 "reflect.h2" }; -#line 642 "reflect.h2" +#line 651 "reflect.h2" class parameter_declaration : public reflection_base { -#line 646 "reflect.h2" +#line 655 "reflect.h2" public: parameter_declaration( parameter_declaration_node* n_, cpp2::impl::in s ); -#line 655 "reflect.h2" +#line 664 "reflect.h2" public: [[nodiscard]] auto get_declaration() const& -> object_declaration; public: [[nodiscard]] auto get_passing_style() const& -> passing_style; @@ -642,10 +642,10 @@ class parameter_declaration public: parameter_declaration(parameter_declaration const& that); public: parameter_declaration(parameter_declaration&& that) noexcept; -#line 662 "reflect.h2" +#line 671 "reflect.h2" }; -#line 675 "reflect.h2" +#line 684 "reflect.h2" using multiplicative_expression = binary_expression<"multiplicative",is_as_expression_node>; using additive_expression = binary_expression<"additive",multiplicative_expression_node>; using shift_expression = binary_expression<"shift",additive_expression_node>; @@ -662,14 +662,14 @@ using assignment_expression = binary_expression<"assignment",logical_or_expressi template class binary_expression : public reflection_base> { -#line 692 "reflect.h2" +#line 701 "reflect.h2" public: binary_expression( binary_expression_node* n_, cpp2::impl::in s ); -#line 701 "reflect.h2" +#line 710 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto lhs_is_id_expression() const& -> bool; public: [[nodiscard]] auto is_standalone_expression() const& -> bool; @@ -694,16 +694,16 @@ public: auto operator=(term_t const& that) -> term_t& ; public: term_t(term_t&& that) noexcept; public: auto operator=(term_t&& that) noexcept -> term_t& ; -#line 719 "reflect.h2" +#line 728 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 796 "reflect.h2" +#line 805 "reflect.h2" public: [[nodiscard]] auto as_expression_list() const& -> expression_list; public: [[nodiscard]] auto as_literal() const& -> std::string; -#line 800 "reflect.h2" +#line 809 "reflect.h2" public: [[nodiscard]] auto get_if_only_a_postfix_expression() const& -> postfix_expression; public: [[nodiscard]] auto get_lhs_postfix_expression() const& -> postfix_expression; @@ -716,49 +716,49 @@ public: auto operator=(term_t&& that) noexcept -> term_t& ; public: binary_expression(binary_expression const& that); public: binary_expression(binary_expression&& that) noexcept; -#line 809 "reflect.h2" +#line 818 "reflect.h2" }; -#line 815 "reflect.h2" +#line 824 "reflect.h2" class expression_list : public reflection_base { -#line 819 "reflect.h2" +#line 828 "reflect.h2" public: expression_list( expression_list_node* n_, cpp2::impl::in s ); -#line 828 "reflect.h2" +#line 837 "reflect.h2" public: [[nodiscard]] auto is_empty() const& -> bool; public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto get_expressions() const& -> std::vector; -#line 841 "reflect.h2" +#line 850 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: expression_list(expression_list const& that); public: expression_list(expression_list&& that) noexcept; -#line 842 "reflect.h2" +#line 851 "reflect.h2" }; -#line 848 "reflect.h2" +#line 857 "reflect.h2" class prefix_expression : public reflection_base { -#line 852 "reflect.h2" +#line 861 "reflect.h2" public: prefix_expression( prefix_expression_node* n_, cpp2::impl::in s ); -#line 861 "reflect.h2" +#line 870 "reflect.h2" public: [[nodiscard]] auto get_ops() const& -> std::vector; -#line 869 "reflect.h2" +#line 878 "reflect.h2" public: [[nodiscard]] auto get_postfix_expression() const& -> postfix_expression; public: [[nodiscard]] auto is_fold_expression() const& -> bool; @@ -778,21 +778,21 @@ class prefix_expression public: prefix_expression(prefix_expression const& that); public: prefix_expression(prefix_expression&& that) noexcept; -#line 884 "reflect.h2" +#line 893 "reflect.h2" }; -#line 890 "reflect.h2" +#line 899 "reflect.h2" class postfix_expression : public reflection_base { -#line 894 "reflect.h2" +#line 903 "reflect.h2" public: postfix_expression( postfix_expression_node* n_, cpp2::impl::in s ); -#line 903 "reflect.h2" +#line 912 "reflect.h2" public: [[nodiscard]] auto get_primary_expression() const& -> primary_expression; public: class term_t { @@ -803,7 +803,7 @@ class postfix_expression public: [[nodiscard]] auto get_op() const& -> std::string_view; -#line 919 "reflect.h2" +#line 928 "reflect.h2" public: [[nodiscard]] auto is_id_expression() const& -> bool; public: [[nodiscard]] auto is_expression_list() const& -> bool; public: [[nodiscard]] auto is_expression() const& -> bool; @@ -814,12 +814,12 @@ class postfix_expression public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 926 "reflect.h2" +#line 935 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 934 "reflect.h2" +#line 943 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -833,7 +833,7 @@ public: term_t(term_t&& that) noexcept; public: [[nodiscard]] auto get_first_token_ignoring_this() const& -> std::string_view; -#line 951 "reflect.h2" +#line 960 "reflect.h2" public: [[nodiscard]] auto starts_with_function_call_with_num_parameters(cpp2::impl::in num) const& -> bool; public: [[nodiscard]] auto is_result_a_temporary_variable() const& -> bool; @@ -841,21 +841,21 @@ public: term_t(term_t&& that) noexcept; public: postfix_expression(postfix_expression const& that); public: postfix_expression(postfix_expression&& that) noexcept; -#line 955 "reflect.h2" +#line 964 "reflect.h2" }; -#line 961 "reflect.h2" +#line 970 "reflect.h2" class template_arg : public reflection_base { -#line 965 "reflect.h2" +#line 974 "reflect.h2" public: template_arg( template_argument* n_, cpp2::impl::in s ); -#line 974 "reflect.h2" +#line 983 "reflect.h2" public: [[nodiscard]] auto is_expression() const& -> bool; public: [[nodiscard]] auto is_type_id() const& -> bool; @@ -866,47 +866,47 @@ class template_arg public: template_arg(template_arg const& that); public: template_arg(template_arg&& that) noexcept; -#line 981 "reflect.h2" +#line 990 "reflect.h2" }; -#line 987 "reflect.h2" +#line 996 "reflect.h2" class unqualified_id : public reflection_base { -#line 991 "reflect.h2" +#line 1000 "reflect.h2" public: unqualified_id( unqualified_id_node* n_, cpp2::impl::in s ); -#line 1000 "reflect.h2" +#line 1009 "reflect.h2" public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto get_identifier() const& -> std::string; -#line 1010 "reflect.h2" +#line 1019 "reflect.h2" public: [[nodiscard]] auto as_token() const& -> std::string; public: [[nodiscard]] auto to_string() const& -> std::string; public: unqualified_id(unqualified_id const& that); public: unqualified_id(unqualified_id&& that) noexcept; -#line 1013 "reflect.h2" +#line 1022 "reflect.h2" }; -#line 1019 "reflect.h2" +#line 1028 "reflect.h2" class qualified_id : public reflection_base { -#line 1023 "reflect.h2" +#line 1032 "reflect.h2" public: qualified_id( qualified_id_node* n_, cpp2::impl::in s ); -#line 1032 "reflect.h2" +#line 1041 "reflect.h2" public: class term_t { private: std::string op; private: unqualified_id unqualified; @@ -918,33 +918,33 @@ class qualified_id public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 1040 "reflect.h2" +#line 1049 "reflect.h2" }; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 1054 "reflect.h2" +#line 1063 "reflect.h2" public: [[nodiscard]] auto as_token() const& -> std::string; public: [[nodiscard]] auto to_string() const& -> std::string; public: qualified_id(qualified_id const& that); public: qualified_id(qualified_id&& that) noexcept; -#line 1057 "reflect.h2" +#line 1066 "reflect.h2" }; -#line 1063 "reflect.h2" +#line 1072 "reflect.h2" class type_id : public reflection_base { -#line 1067 "reflect.h2" +#line 1076 "reflect.h2" public: type_id( type_id_node* n_, cpp2::impl::in s ); -#line 1082 "reflect.h2" +#line 1091 "reflect.h2" public: [[nodiscard]] auto is_postfix_expression() const& -> bool; public: [[nodiscard]] auto is_qualified_id() const& -> bool; public: [[nodiscard]] auto is_unqualified_id() const& -> bool; @@ -958,7 +958,7 @@ class type_id public: [[nodiscard]] auto as_qualified_id() const& -> qualified_id; public: [[nodiscard]] auto as_unqualified_id() const& -> unqualified_id; -#line 1096 "reflect.h2" +#line 1105 "reflect.h2" public: [[nodiscard]] auto as_keyword() const& -> std::string; public: [[nodiscard]] auto as_token() const& -> std::string; @@ -966,21 +966,21 @@ class type_id public: type_id(type_id const& that); public: type_id(type_id&& that) noexcept; -#line 1100 "reflect.h2" +#line 1109 "reflect.h2" }; -#line 1106 "reflect.h2" +#line 1115 "reflect.h2" class primary_expression : public reflection_base { -#line 1110 "reflect.h2" +#line 1119 "reflect.h2" public: primary_expression( primary_expression_node* n_, cpp2::impl::in s ); -#line 1125 "reflect.h2" +#line 1134 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -998,21 +998,21 @@ class primary_expression public: primary_expression(primary_expression const& that); public: primary_expression(primary_expression&& that) noexcept; -#line 1139 "reflect.h2" +#line 1148 "reflect.h2" }; -#line 1145 "reflect.h2" +#line 1154 "reflect.h2" class id_expression : public reflection_base { -#line 1149 "reflect.h2" +#line 1158 "reflect.h2" public: id_expression( id_expression_node* n_, cpp2::impl::in s ); -#line 1164 "reflect.h2" +#line 1173 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_empty() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; @@ -1028,21 +1028,21 @@ class id_expression public: id_expression(id_expression const& that); public: id_expression(id_expression&& that) noexcept; -#line 1175 "reflect.h2" +#line 1184 "reflect.h2" }; -#line 1181 "reflect.h2" +#line 1190 "reflect.h2" class expression : public reflection_base { -#line 1185 "reflect.h2" +#line 1194 "reflect.h2" public: expression( expression_node* n_, cpp2::impl::in s ); -#line 1194 "reflect.h2" +#line 1203 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_standalone_expression() const& -> bool; public: [[nodiscard]] auto subexpression_count() const& -> int; @@ -1059,10 +1059,10 @@ struct get_lhs_rhs_if_simple_assignment_ret { postfix_expression lhs; logical_or -#line 1210 "reflect.h2" +#line 1219 "reflect.h2" public: [[nodiscard]] auto get_lhs_rhs_if_simple_assignment() const& -> get_lhs_rhs_if_simple_assignment_ret; -#line 1221 "reflect.h2" +#line 1230 "reflect.h2" public: [[nodiscard]] auto as_assignment_expression() const& -> assignment_expression; public: [[nodiscard]] auto as_expression_list() const& -> expression_list; public: [[nodiscard]] auto as_literal() const& -> std::string; @@ -1072,21 +1072,21 @@ struct get_lhs_rhs_if_simple_assignment_ret { postfix_expression lhs; logical_or public: expression(expression const& that); public: expression(expression&& that) noexcept; -#line 1226 "reflect.h2" +#line 1235 "reflect.h2" }; -#line 1232 "reflect.h2" +#line 1241 "reflect.h2" class is_as_expression : public reflection_base { -#line 1236 "reflect.h2" +#line 1245 "reflect.h2" public: is_as_expression( is_as_expression_node* n_, cpp2::impl::in s ); -#line 1245 "reflect.h2" +#line 1254 "reflect.h2" public: class term_t { private: std::string op; private: expression expr; @@ -1098,14 +1098,14 @@ class is_as_expression public: term_t(term_t const& that); public: term_t(term_t&& that) noexcept; -#line 1253 "reflect.h2" +#line 1262 "reflect.h2" }; public: [[nodiscard]] auto get_expression() const& -> prefix_expression; public: [[nodiscard]] auto get_terms() const& -> auto; -#line 1263 "reflect.h2" +#line 1272 "reflect.h2" public: [[nodiscard]] auto is_fold_expression() const& -> bool; public: [[nodiscard]] auto is_identifier() const& -> bool; public: [[nodiscard]] auto is_id_expression() const& -> bool; @@ -1118,27 +1118,27 @@ public: term_t(term_t&& that) noexcept; public: [[nodiscard]] auto get_identifier() const& -> std::string_view; -#line 1279 "reflect.h2" +#line 1288 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: virtual ~is_as_expression() noexcept; public: is_as_expression(is_as_expression const& that); public: is_as_expression(is_as_expression&& that) noexcept; -#line 1280 "reflect.h2" +#line 1289 "reflect.h2" }; -#line 1293 "reflect.h2" +#line 1302 "reflect.h2" class statement : public reflection_base { -#line 1297 "reflect.h2" +#line 1306 "reflect.h2" public: statement( statement_node* n_, cpp2::impl::in s ); -#line 1306 "reflect.h2" +#line 1315 "reflect.h2" public: [[nodiscard]] auto is_expression_statement() const& -> bool; public: [[nodiscard]] auto is_compound_statement() const& -> bool; public: [[nodiscard]] auto is_selection_statement() const& -> bool; @@ -1157,71 +1157,71 @@ class statement public: [[nodiscard]] auto as_return_statement() const& -> return_statement; public: [[nodiscard]] auto as_iteration_statement() const& -> iteration_statement; -#line 1328 "reflect.h2" +#line 1337 "reflect.h2" public: [[nodiscard]] auto to_string() const& -> std::string; public: virtual ~statement() noexcept; public: statement(statement const& that); public: statement(statement&& that) noexcept; -#line 1329 "reflect.h2" +#line 1338 "reflect.h2" }; -#line 1335 "reflect.h2" +#line 1344 "reflect.h2" class expression_statement : public reflection_base { -#line 1339 "reflect.h2" +#line 1348 "reflect.h2" public: expression_statement( expression_statement_node* n_, cpp2::impl::in s ); -#line 1348 "reflect.h2" +#line 1357 "reflect.h2" public: [[nodiscard]] auto get_expression() const& -> expression; public: [[nodiscard]] auto to_string() const& -> std::string; public: expression_statement(expression_statement const& that); public: expression_statement(expression_statement&& that) noexcept; -#line 1351 "reflect.h2" +#line 1360 "reflect.h2" }; -#line 1357 "reflect.h2" +#line 1366 "reflect.h2" class compound_statement : public reflection_base { -#line 1361 "reflect.h2" +#line 1370 "reflect.h2" public: compound_statement( compound_statement_node* n_, cpp2::impl::in s ); -#line 1370 "reflect.h2" +#line 1379 "reflect.h2" public: [[nodiscard]] auto get_statements() const& -> std::vector; -#line 1380 "reflect.h2" +#line 1389 "reflect.h2" public: auto add_statement(cpp2::impl::in source, cpp2::impl::in before_position = 0) & -> void; public: compound_statement(compound_statement const& that); public: compound_statement(compound_statement&& that) noexcept; -#line 1390 "reflect.h2" +#line 1399 "reflect.h2" }; -#line 1396 "reflect.h2" +#line 1405 "reflect.h2" class selection_statement : public reflection_base { -#line 1400 "reflect.h2" +#line 1409 "reflect.h2" public: selection_statement( selection_statement_node* n_, cpp2::impl::in s ); -#line 1409 "reflect.h2" +#line 1418 "reflect.h2" public: [[nodiscard]] auto has_false_branch_in_source_code() const& -> bool; public: [[nodiscard]] auto has_false_branch() const& -> bool; @@ -1232,42 +1232,42 @@ class selection_statement public: selection_statement(selection_statement const& that); public: selection_statement(selection_statement&& that) noexcept; -#line 1416 "reflect.h2" +#line 1425 "reflect.h2" }; -#line 1422 "reflect.h2" +#line 1431 "reflect.h2" class return_statement : public reflection_base { -#line 1426 "reflect.h2" +#line 1435 "reflect.h2" public: return_statement( return_statement_node* n_, cpp2::impl::in s ); -#line 1435 "reflect.h2" +#line 1444 "reflect.h2" public: [[nodiscard]] auto has_expression() const& -> bool; public: [[nodiscard]] auto get_expression() const& -> expression; public: return_statement(return_statement const& that); public: return_statement(return_statement&& that) noexcept; -#line 1438 "reflect.h2" +#line 1447 "reflect.h2" }; -#line 1444 "reflect.h2" +#line 1453 "reflect.h2" class iteration_statement : public reflection_base { -#line 1448 "reflect.h2" +#line 1457 "reflect.h2" public: iteration_statement( iteration_statement_node* n_, cpp2::impl::in s ); -#line 1457 "reflect.h2" +#line 1466 "reflect.h2" public: [[nodiscard]] auto is_do() const& -> bool; public: [[nodiscard]] auto is_while() const& -> bool; public: [[nodiscard]] auto is_for() const& -> bool; @@ -1283,68 +1283,68 @@ class iteration_statement public: iteration_statement(iteration_statement const& that); public: iteration_statement(iteration_statement&& that) noexcept; -#line 1469 "reflect.h2" +#line 1478 "reflect.h2" }; -#line 1484 "reflect.h2" +#line 1493 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 1504 "reflect.h2" +#line 1513 "reflect.h2" auto interface(meta::type_declaration& t) -> void; -#line 1552 "reflect.h2" +#line 1561 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void; -#line 1597 "reflect.h2" +#line 1606 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::impl::in ordering ) -> void; -#line 1626 "reflect.h2" +#line 1635 "reflect.h2" auto ordered(meta::type_declaration& t) -> void; -#line 1634 "reflect.h2" +#line 1643 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void; -#line 1642 "reflect.h2" +#line 1651 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void; -#line 1664 "reflect.h2" +#line 1673 "reflect.h2" auto copyable(meta::type_declaration& t) -> void; -#line 1696 "reflect.h2" +#line 1705 "reflect.h2" auto copy_constructible(meta::type_declaration& t) -> void; -#line 1728 "reflect.h2" +#line 1737 "reflect.h2" auto hashable(meta::type_declaration& t) -> void; -#line 1761 "reflect.h2" +#line 1770 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void; -#line 1789 "reflect.h2" +#line 1798 "reflect.h2" auto value(meta::type_declaration& t) -> void; -#line 1795 "reflect.h2" +#line 1804 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 1801 "reflect.h2" +#line 1810 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 1830 "reflect.h2" +#line 1839 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void; -#line 1872 "reflect.h2" +#line 1881 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void; -#line 1941 "reflect.h2" +#line 1950 "reflect.h2" class value_member_info { public: std::string name; public: std::string type; public: std::string value; public: value_member_info(auto const& name_, auto const& type_, auto const& value_); -#line 1945 "reflect.h2" +#line 1954 "reflect.h2" }; auto basic_enum( @@ -1353,301 +1353,301 @@ auto basic_enum( cpp2::impl::in bitwise ) -> void; -#line 2211 "reflect.h2" +#line 2220 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void; -#line 2238 "reflect.h2" +#line 2247 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void; -#line 2284 "reflect.h2" +#line 2293 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void; -#line 2435 "reflect.h2" +#line 2444 "reflect.h2" auto print(cpp2::impl::in t) -> void; -#line 2446 "reflect.h2" +#line 2455 "reflect.h2" auto noisy(cpp2::impl::in t) -> void; -#line 2467 "reflect.h2" +#line 2476 "reflect.h2" auto sample_print(cpp2::impl::in s, cpp2::impl::in indent) -> void; -#line 2475 "reflect.h2" +#line 2484 "reflect.h2" class simple_traverser { public: virtual auto pre_traverse(cpp2::impl::in decl) -> void; -#line 2481 "reflect.h2" +#line 2490 "reflect.h2" public: virtual auto traverse(cpp2::impl::in decl) -> void; -#line 2501 "reflect.h2" +#line 2510 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in f) -> void; -#line 2505 "reflect.h2" +#line 2514 "reflect.h2" public: virtual auto traverse(cpp2::impl::in f) -> void; -#line 2526 "reflect.h2" +#line 2535 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in o) -> void; -#line 2530 "reflect.h2" +#line 2539 "reflect.h2" public: virtual auto traverse(cpp2::impl::in o) -> void; -#line 2538 "reflect.h2" +#line 2547 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in t) -> void; -#line 2542 "reflect.h2" +#line 2551 "reflect.h2" public: virtual auto traverse(cpp2::impl::in t) -> void; -#line 2550 "reflect.h2" +#line 2559 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in t) -> void; -#line 2554 "reflect.h2" +#line 2563 "reflect.h2" public: virtual auto traverse(cpp2::impl::in t) -> void; -#line 2559 "reflect.h2" +#line 2568 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2563 "reflect.h2" +#line 2572 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2598 "reflect.h2" +#line 2607 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2602 "reflect.h2" +#line 2611 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2612 "reflect.h2" +#line 2621 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2616 "reflect.h2" +#line 2625 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2624 "reflect.h2" +#line 2633 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2628 "reflect.h2" +#line 2637 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2647 "reflect.h2" +#line 2656 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in stmt) -> void; -#line 2651 "reflect.h2" +#line 2660 "reflect.h2" public: virtual auto traverse(cpp2::impl::in stmt) -> void; -#line 2662 "reflect.h2" +#line 2671 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in expr) -> void; -#line 2668 "reflect.h2" +#line 2677 "reflect.h2" public: virtual auto traverse(cpp2::impl::in expr) -> void; -#line 2682 "reflect.h2" +#line 2691 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2699 "reflect.h2" +#line 2708 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2710 "reflect.h2" +#line 2719 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2727 "reflect.h2" +#line 2736 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2739 "reflect.h2" +#line 2748 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2756 "reflect.h2" +#line 2765 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2767 "reflect.h2" +#line 2776 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2784 "reflect.h2" +#line 2793 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2795 "reflect.h2" +#line 2804 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2812 "reflect.h2" +#line 2821 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2824 "reflect.h2" +#line 2833 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2841 "reflect.h2" +#line 2850 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2853 "reflect.h2" +#line 2862 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2870 "reflect.h2" +#line 2879 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2881 "reflect.h2" +#line 2890 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2898 "reflect.h2" +#line 2907 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2909 "reflect.h2" +#line 2918 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2926 "reflect.h2" +#line 2935 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2937 "reflect.h2" +#line 2946 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2954 "reflect.h2" +#line 2963 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2965 "reflect.h2" +#line 2974 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 2982 "reflect.h2" +#line 2991 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 2994 "reflect.h2" +#line 3003 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in binexpr) -> void; -#line 3011 "reflect.h2" +#line 3020 "reflect.h2" public: virtual auto traverse(cpp2::impl::in binexpr) -> void; -#line 3022 "reflect.h2" +#line 3031 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in isas) -> void; -#line 3038 "reflect.h2" +#line 3047 "reflect.h2" public: virtual auto traverse(cpp2::impl::in isas) -> void; -#line 3049 "reflect.h2" +#line 3058 "reflect.h2" public: virtual auto traverse(cpp2::impl::in exprs) -> void; -#line 3056 "reflect.h2" +#line 3065 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in prefix) -> void; -#line 3072 "reflect.h2" +#line 3081 "reflect.h2" public: virtual auto traverse(cpp2::impl::in prefix) -> void; -#line 3077 "reflect.h2" +#line 3086 "reflect.h2" public: virtual auto pre_traverse(cpp2::impl::in postfix) -> void; -#line 3093 "reflect.h2" +#line 3102 "reflect.h2" public: virtual auto traverse(cpp2::impl::in postfix) -> void; -#line 3112 "reflect.h2" +#line 3121 "reflect.h2" public: virtual auto traverse(cpp2::impl::in uid) -> void; -#line 3118 "reflect.h2" +#line 3127 "reflect.h2" public: virtual auto traverse(cpp2::impl::in qid) -> void; -#line 3128 "reflect.h2" +#line 3137 "reflect.h2" public: virtual auto traverse(cpp2::impl::in tid) -> void; -#line 3145 "reflect.h2" +#line 3154 "reflect.h2" public: virtual auto traverse(cpp2::impl::in primary) -> void; -#line 3165 "reflect.h2" +#line 3174 "reflect.h2" public: virtual auto traverse(cpp2::impl::in idexpr) -> void; public: simple_traverser() = default; public: simple_traverser(simple_traverser const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(simple_traverser const&) -> void = delete; -#line 3180 "reflect.h2" +#line 3189 "reflect.h2" }; -#line 3193 "reflect.h2" +#line 3202 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void; -#line 3215 "reflect.h2" +#line 3224 "reflect.h2" auto sample_traverser(cpp2::impl::in f, cpp2::impl::in indent = 0) -> void; -#line 3245 "reflect.h2" +#line 3254 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void; -#line 3255 "reflect.h2" +#line 3264 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3274 "reflect.h2" +#line 3283 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent = 0) -> void; -#line 3293 "reflect.h2" +#line 3302 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3340 "reflect.h2" +#line 3349 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3357 "reflect.h2" +#line 3366 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3367 "reflect.h2" +#line 3376 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void; -#line 3399 "reflect.h2" +#line 3408 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void; -#line 3413 "reflect.h2" +#line 3422 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3443 "reflect.h2" +#line 3452 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3473 "reflect.h2" +#line 3482 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3503 "reflect.h2" +#line 3512 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3533 "reflect.h2" +#line 3542 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3563 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3593 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3623 "reflect.h2" +#line 3632 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3653 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3683 "reflect.h2" +#line 3692 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3713 "reflect.h2" +#line 3722 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3743 "reflect.h2" +#line 3752 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void; -#line 3773 "reflect.h2" +#line 3782 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void; -#line 3799 "reflect.h2" +#line 3808 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void; -#line 3814 "reflect.h2" +#line 3823 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void; -#line 3838 "reflect.h2" +#line 3847 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void; -#line 3871 "reflect.h2" +#line 3880 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void; -#line 3882 "reflect.h2" +#line 3891 "reflect.h2" auto sample_traverser(cpp2::impl::in qid, cpp2::impl::in indent) -> void; -#line 3898 "reflect.h2" +#line 3907 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void; -#line 3915 "reflect.h2" +#line 3924 "reflect.h2" auto sample_traverser(cpp2::impl::in primary, cpp2::impl::in indent) -> void; -#line 3935 "reflect.h2" +#line 3944 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void; -#line 3957 "reflect.h2" +#line 3966 "reflect.h2" class autodiff_special_func { public: std::string name; public: int n_args; @@ -1659,18 +1659,18 @@ class autodiff_special_func { public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = "", cpp2::impl::in code_higher_order_ = ""); -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" public: autodiff_special_func(autodiff_special_func const& that); -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" public: autodiff_special_func(autodiff_special_func&& that) noexcept; -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; -#line 3984 "reflect.h2" +#line 3993 "reflect.h2" }; class autodiff_declaration_stack_item { @@ -1684,19 +1684,19 @@ class autodiff_declaration_stack_item { using lookup_declaration_ret = std::vector; -#line 3998 "reflect.h2" +#line 4007 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4007 "reflect.h2" +#line 4016 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4021 "reflect.h2" +#line 4030 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, true, false, "_rd_ = cos(_a1_) * _ad1_;\n" @@ -1722,11 +1722,11 @@ class autodiff_context { "_o_.push_back(_a1_);\n" "_od_.push_back(_ad1_);\n")}; -#line 4047 "reflect.h2" +#line 4056 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4051 "reflect.h2" +#line 4060 "reflect.h2" public: std::string ad_type {"double"}; public: std::map> declaration_map {}; @@ -1734,62 +1734,62 @@ class autodiff_context { public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4073 "reflect.h2" +#line 4082 "reflect.h2" public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4084 "reflect.h2" +#line 4093 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4092 "reflect.h2" +#line 4101 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4101 "reflect.h2" +#line 4110 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; using lookup_function_declaration_ret = std::vector; -#line 4124 "reflect.h2" +#line 4133 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code; }; -#line 4134 "reflect.h2" +#line 4143 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4153 "reflect.h2" +#line 4162 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4161 "reflect.h2" +#line 4170 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4181 "reflect.h2" +#line 4190 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4191 "reflect.h2" +#line 4200 "reflect.h2" public: auto enter_function() & -> void; -#line 4195 "reflect.h2" +#line 4204 "reflect.h2" public: auto leave_function() & -> void; -#line 4198 "reflect.h2" +#line 4207 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4211 "reflect.h2" +#line 4220 "reflect.h2" public: auto pop_stack() & -> void; -#line 4228 "reflect.h2" +#line 4235 "reflect.h2" public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4233 "reflect.h2" +#line 4240 "reflect.h2" }; class autodiff_handler_base { @@ -1798,21 +1798,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4240 "reflect.h2" +#line 4247 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4244 "reflect.h2" +#line 4251 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4247 "reflect.h2" +#line 4254 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4253 "reflect.h2" +#line 4260 "reflect.h2" public: using base = simple_traverser; public: std::string lhs; @@ -1821,214 +1821,214 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); -#line 4270 "reflect.h2" +#line 4277 "reflect.h2" public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; -#line 4289 "reflect.h2" +#line 4296 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4298 "reflect.h2" +#line 4305 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4336 "reflect.h2" +#line 4343 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4458 "reflect.h2" +#line 4465 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; -#line 4491 "reflect.h2" +#line 4498 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4495 "reflect.h2" +#line 4502 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4499 "reflect.h2" +#line 4506 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4503 "reflect.h2" +#line 4510 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4507 "reflect.h2" +#line 4514 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4511 "reflect.h2" +#line 4518 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4515 "reflect.h2" +#line 4522 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4519 "reflect.h2" +#line 4526 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4523 "reflect.h2" +#line 4530 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4527 "reflect.h2" +#line 4534 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4531 "reflect.h2" +#line 4538 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4535 "reflect.h2" +#line 4542 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4559 "reflect.h2" +#line 4566 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4616 "reflect.h2" +#line 4623 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4620 "reflect.h2" +#line 4627 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4625 "reflect.h2" +#line 4632 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4652 "reflect.h2" +#line 4659 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4683 "reflect.h2" +#line 4690 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4689 "reflect.h2" +#line 4696 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4698 "reflect.h2" +#line 4705 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4703 "reflect.h2" +#line 4710 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4708 "reflect.h2" +#line 4715 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4726 "reflect.h2" +#line 4733 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4731 "reflect.h2" +#line 4738 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4736 "reflect.h2" +#line 4743 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4741 "reflect.h2" +#line 4748 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4749 "reflect.h2" +#line 4756 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4765 "reflect.h2" +#line 4772 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4812 "reflect.h2" +#line 4819 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4823 "reflect.h2" +#line 4830 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4851 "reflect.h2" +#line 4858 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4856 "reflect.h2" +#line 4863 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4860 "reflect.h2" +#line 4867 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4864 "reflect.h2" +#line 4871 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4868 "reflect.h2" +#line 4875 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4872 "reflect.h2" +#line 4879 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4876 "reflect.h2" +#line 4883 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4880 "reflect.h2" +#line 4887 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4884 "reflect.h2" +#line 4891 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4888 "reflect.h2" +#line 4895 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4892 "reflect.h2" +#line 4899 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4896 "reflect.h2" +#line 4903 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4900 "reflect.h2" +#line 4907 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4904 "reflect.h2" +#line 4911 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4909 "reflect.h2" +#line 4916 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4938 "reflect.h2" +#line 4945 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4942 "reflect.h2" +#line 4949 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4948 "reflect.h2" +#line 4955 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4957 "reflect.h2" +#line 4964 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4962 "reflect.h2" +#line 4969 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5026 "reflect.h2" +#line 5033 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5031 "reflect.h2" +#line 5038 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5046 "reflect.h2" +#line 5053 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5051 "reflect.h2" +#line 5058 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5054 "reflect.h2" +#line 5061 "reflect.h2" }; -#line 5057 "reflect.h2" +#line 5064 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5145 "reflect.h2" +#line 5152 "reflect.h2" using error_func = std::function x)>; -#line 5149 "reflect.h2" +#line 5156 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2063,20 +2063,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5157 "reflect.h2" +#line 5164 "reflect.h2" }; -#line 5165 "reflect.h2" +#line 5172 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5173 "reflect.h2" +#line 5180 "reflect.h2" public: explicit regex_token(); -#line 5178 "reflect.h2" +#line 5185 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2088,103 +2088,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5184 "reflect.h2" +#line 5191 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5190 "reflect.h2" +#line 5197 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5196 "reflect.h2" +#line 5203 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5203 "reflect.h2" +#line 5210 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5207 "reflect.h2" +#line 5214 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5208 "reflect.h2" +#line 5215 "reflect.h2" }; -#line 5211 "reflect.h2" +#line 5218 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5217 "reflect.h2" +#line 5224 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5224 "reflect.h2" +#line 5231 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5228 "reflect.h2" +#line 5235 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5229 "reflect.h2" +#line 5236 "reflect.h2" }; -#line 5232 "reflect.h2" +#line 5239 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5238 "reflect.h2" +#line 5245 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5242 "reflect.h2" +#line 5249 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5246 "reflect.h2" +#line 5253 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5247 "reflect.h2" +#line 5254 "reflect.h2" }; -#line 5250 "reflect.h2" +#line 5257 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5256 "reflect.h2" +#line 5263 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5263 "reflect.h2" +#line 5270 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5269 "reflect.h2" +#line 5276 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5275 "reflect.h2" +#line 5282 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5283 "reflect.h2" +#line 5290 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2192,10 +2192,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5295 "reflect.h2" +#line 5302 "reflect.h2" }; -#line 5298 "reflect.h2" +#line 5305 "reflect.h2" // // Parse and generation context. // @@ -2211,33 +2211,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5318 "reflect.h2" +#line 5325 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5325 "reflect.h2" +#line 5332 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5337 "reflect.h2" +#line 5344 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5342 "reflect.h2" +#line 5349 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5346 "reflect.h2" +#line 5353 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5360 "reflect.h2" +#line 5367 "reflect.h2" }; -#line 5363 "reflect.h2" +#line 5370 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2250,25 +2250,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5381 "reflect.h2" +#line 5388 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5387 "reflect.h2" +#line 5394 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5394 "reflect.h2" +#line 5401 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5401 "reflect.h2" +#line 5408 "reflect.h2" }; -#line 5404 "reflect.h2" +#line 5411 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2284,7 +2284,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5420 "reflect.h2" +#line 5427 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2292,64 +2292,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5431 "reflect.h2" +#line 5438 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5444 "reflect.h2" +#line 5451 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5452 "reflect.h2" +#line 5459 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5456 "reflect.h2" +#line 5463 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5460 "reflect.h2" +#line 5467 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5472 "reflect.h2" +#line 5479 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5479 "reflect.h2" +#line 5486 "reflect.h2" public: auto next_alternative() & -> void; -#line 5485 "reflect.h2" +#line 5492 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5491 "reflect.h2" +#line 5498 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5495 "reflect.h2" +#line 5502 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5506 "reflect.h2" +#line 5513 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5510 "reflect.h2" +#line 5517 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5516 "reflect.h2" +#line 5523 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5520 "reflect.h2" +#line 5527 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5527 "reflect.h2" +#line 5534 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5538 "reflect.h2" +#line 5545 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2357,51 +2357,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5582 "reflect.h2" +#line 5589 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5594 "reflect.h2" +#line 5601 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5607 "reflect.h2" +#line 5614 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5630 "reflect.h2" +#line 5637 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5647 "reflect.h2" +#line 5654 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5668 "reflect.h2" +#line 5675 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5678 "reflect.h2" +#line 5685 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5682 "reflect.h2" +#line 5689 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5738 "reflect.h2" +#line 5745 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5777 "reflect.h2" +#line 5784 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5792 "reflect.h2" +#line 5799 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2413,10 +2413,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5803 "reflect.h2" +#line 5810 "reflect.h2" }; -#line 5806 "reflect.h2" +#line 5813 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2426,16 +2426,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5820 "reflect.h2" +#line 5827 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5823 "reflect.h2" +#line 5830 "reflect.h2" }; -#line 5826 "reflect.h2" +#line 5833 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2455,68 +2455,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5848 "reflect.h2" +#line 5855 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5854 "reflect.h2" +#line 5861 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5863 "reflect.h2" +#line 5870 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5874 "reflect.h2" +#line 5881 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5881 "reflect.h2" +#line 5888 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5901 "reflect.h2" +#line 5908 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5911 "reflect.h2" +#line 5918 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5934 "reflect.h2" +#line 5941 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5942 "reflect.h2" +#line 5949 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5946 "reflect.h2" +#line 5953 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5952 "reflect.h2" +#line 5959 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5958 "reflect.h2" +#line 5965 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5968 "reflect.h2" +#line 5975 "reflect.h2" public: auto finish_context() & -> void; -#line 5976 "reflect.h2" +#line 5983 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5982 "reflect.h2" +#line 5989 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5986 "reflect.h2" +#line 5993 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5990 "reflect.h2" +#line 5997 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6014 "reflect.h2" +#line 6021 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2524,7 +2524,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6020 "reflect.h2" +#line 6027 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2544,27 +2544,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6039 "reflect.h2" +#line 6046 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6045 "reflect.h2" +#line 6052 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6052 "reflect.h2" +#line 6059 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6069 "reflect.h2" +#line 6076 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6076 "reflect.h2" +#line 6083 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6089 "reflect.h2" +#line 6096 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2572,19 +2572,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6101 "reflect.h2" +#line 6108 "reflect.h2" }; -#line 6104 "reflect.h2" +#line 6111 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6110 "reflect.h2" +#line 6117 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6114 "reflect.h2" +#line 6121 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2592,7 +2592,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6119 "reflect.h2" +#line 6126 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2600,17 +2600,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6127 "reflect.h2" +#line 6134 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6138 "reflect.h2" +#line 6145 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6146 "reflect.h2" +#line 6153 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2618,7 +2618,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6149 "reflect.h2" +#line 6156 "reflect.h2" }; // Regex syntax: a @@ -2626,34 +2626,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6157 "reflect.h2" +#line 6164 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6166 "reflect.h2" +#line 6173 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6172 "reflect.h2" +#line 6179 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6176 "reflect.h2" +#line 6183 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6199 "reflect.h2" +#line 6206 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6220 "reflect.h2" +#line 6227 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6238 "reflect.h2" +#line 6245 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6253 "reflect.h2" +#line 6260 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6259 "reflect.h2" +#line 6266 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2661,33 +2661,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6263 "reflect.h2" +#line 6270 "reflect.h2" }; -#line 6266 "reflect.h2" +#line 6273 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6272 "reflect.h2" +#line 6279 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6284 "reflect.h2" +#line 6291 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6410 "reflect.h2" +#line 6417 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6419 "reflect.h2" +#line 6426 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6424 "reflect.h2" +#line 6431 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2695,20 +2695,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6431 "reflect.h2" +#line 6438 "reflect.h2" }; -#line 6434 "reflect.h2" +#line 6441 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6475 "reflect.h2" +#line 6482 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6486 "reflect.h2" +#line 6493 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2718,20 +2718,20 @@ class class_token class group_ref_token : public regex_token { -#line 6496 "reflect.h2" +#line 6503 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6508 "reflect.h2" +#line 6515 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6609 "reflect.h2" +#line 6616 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6613 "reflect.h2" +#line 6620 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2739,10 +2739,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6616 "reflect.h2" +#line 6623 "reflect.h2" }; -#line 6619 "reflect.h2" +#line 6626 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2756,29 +2756,29 @@ class group_ref_token class group_token : public regex_token { -#line 6633 "reflect.h2" +#line 6640 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6655 "reflect.h2" +#line 6662 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6669 "reflect.h2" +#line 6676 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6828 "reflect.h2" +#line 6835 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6836 "reflect.h2" +#line 6843 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6854 "reflect.h2" +#line 6861 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6885 "reflect.h2" +#line 6892 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2787,25 +2787,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6892 "reflect.h2" +#line 6899 "reflect.h2" }; -#line 6895 "reflect.h2" +#line 6902 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6936 "reflect.h2" +#line 6943 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6956 "reflect.h2" +#line 6963 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6972 "reflect.h2" +#line 6979 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2813,20 +2813,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6980 "reflect.h2" +#line 6987 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6989 "reflect.h2" +#line 6996 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7000 "reflect.h2" +#line 7007 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7007 "reflect.h2" +#line 7014 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2834,26 +2834,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7010 "reflect.h2" +#line 7017 "reflect.h2" }; -#line 7013 "reflect.h2" +#line 7020 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7041 "reflect.h2" +#line 7048 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7069 "reflect.h2" +#line 7076 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7075 "reflect.h2" +#line 7082 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2863,22 +2863,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7155 "reflect.h2" +#line 7162 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7167 "reflect.h2" +#line 7174 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7180 "reflect.h2" +#line 7187 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7199 "reflect.h2" +#line 7206 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7209 "reflect.h2" +#line 7216 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7220 "reflect.h2" +#line 7227 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2886,16 +2886,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7223 "reflect.h2" +#line 7230 "reflect.h2" }; -#line 7226 "reflect.h2" +#line 7233 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7232 "reflect.h2" +#line 7239 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2904,7 +2904,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7262 "reflect.h2" +#line 7269 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2913,14 +2913,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7284 "reflect.h2" +#line 7291 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7306 "reflect.h2" +#line 7313 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2941,24 +2941,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7329 "reflect.h2" +#line 7336 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7364 "reflect.h2" +#line 7371 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7378 "reflect.h2" +#line 7385 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7390 "reflect.h2" +#line 7397 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7445 "reflect.h2" +#line 7452 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2969,7 +2969,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7571 "reflect.h2" +#line 7578 "reflect.h2" } } @@ -3678,8 +3678,17 @@ object_declaration::object_declaration(object_declaration&& that) noexcept if (!(CPP2_UFCS(is_declaration)((*cpp2::impl::assert_not_null(decl))))) { error("cannot add a member that is not a declaration"); } - require(CPP2_UFCS(add_type_member)((*cpp2::impl::assert_not_null(n)), std::move(cpp2::move(decl))), + + if (is_namespace()) { + require(CPP2_UFCS(add_namespace_member)((*cpp2::impl::assert_not_null(n)), std::move(cpp2::move(decl))), std::string("unexpected error while attempting to add member:\n") + source); + + } + else { + if (cpp2::cpp2_default.is_active() && !(is_type()) ) { cpp2::cpp2_default.report_violation(""); } + require(CPP2_UFCS(add_type_member)((*cpp2::impl::assert_not_null(n)), std::move(cpp2::move(decl))), + std::string("unexpected error while attempting to add member:\n") + source); + } } type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_declaration const& that) @@ -3687,36 +3696,36 @@ object_declaration::object_declaration(object_declaration&& that) noexcept type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 565 "reflect.h2" +#line 574 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } -#line 570 "reflect.h2" +#line 579 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_type)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } } -#line 576 "reflect.h2" +#line 585 "reflect.h2" [[nodiscard]] auto type_declaration::is_polymorphic() const& -> bool { return CPP2_UFCS(is_polymorphic)((*cpp2::impl::assert_not_null(n))); } -#line 577 "reflect.h2" +#line 586 "reflect.h2" [[nodiscard]] auto type_declaration::is_final() const& -> bool { return CPP2_UFCS(is_type_final)((*cpp2::impl::assert_not_null(n))); } -#line 578 "reflect.h2" +#line 587 "reflect.h2" [[nodiscard]] auto type_declaration::make_final() & -> bool { return CPP2_UFCS(make_type_final)((*cpp2::impl::assert_not_null(n))); } -#line 580 "reflect.h2" +#line 589 "reflect.h2" [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 587 "reflect.h2" +#line 596 "reflect.h2" { cpp2::impl::deferred_init out_this_in_that; cpp2::impl::deferred_init out_this_move_that; cpp2::impl::deferred_init inout_this_in_that; cpp2::impl::deferred_init inout_this_move_that; -#line 588 "reflect.h2" +#line 597 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::impl::assert_not_null(n)))}; out_this_in_that.construct(declared.out_this_in_that != nullptr); out_this_move_that.construct(declared.out_this_move_that != nullptr); @@ -3725,13 +3734,13 @@ type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_d return { std::move(out_this_in_that.value()), std::move(out_this_move_that.value()), std::move(inout_this_in_that.value()), std::move(inout_this_move_that.value()) }; // NOLINT(performance-move-const-arg) } -#line 596 "reflect.h2" +#line 605 "reflect.h2" [[nodiscard]] auto type_declaration::disable_member_function_generation() & -> decltype(auto) { return CPP2_UFCS(type_disable_member_function_generation)((*cpp2::impl::assert_not_null(n))); } // At some point we may want to allow this also for namespaces, but for now only types -#line 599 "reflect.h2" +#line 608 "reflect.h2" [[nodiscard]] auto type_declaration::remove_marked_members() & -> decltype(auto) { return CPP2_UFCS(type_remove_marked_members)((*cpp2::impl::assert_not_null(n))); } -#line 600 "reflect.h2" +#line 609 "reflect.h2" [[nodiscard]] auto type_declaration::remove_all_members() & -> decltype(auto) { return CPP2_UFCS(type_remove_all_members)((*cpp2::impl::assert_not_null(n))); } type_declaration::type_declaration(type_declaration const& that) @@ -3739,14 +3748,14 @@ type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_d type_declaration::type_declaration(type_declaration&& that) noexcept : type_or_namespace_declaration{ static_cast(that) }{} -#line 608 "reflect.h2" +#line 617 "reflect.h2" namespace_declaration::namespace_declaration( declaration_node* n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } -#line 613 "reflect.h2" +#line 622 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_namespace)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } @@ -3757,19 +3766,19 @@ type_declaration::type_declaration(type_declaration&& that) noexcept namespace_declaration::namespace_declaration(namespace_declaration&& that) noexcept : type_or_namespace_declaration{ static_cast(that) }{} -#line 620 "reflect.h2" +#line 629 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // -#line 627 "reflect.h2" +#line 636 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::impl::in s ) : declaration{ n_, s } -#line 632 "reflect.h2" +#line 641 "reflect.h2" { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_alias)((*cpp2::impl::assert_not_null(n)))) ) { cpp2::cpp2_default.report_violation(""); } @@ -3780,35 +3789,35 @@ namespace_declaration::namespace_declaration(namespace_declaration&& that) noexc alias_declaration::alias_declaration(alias_declaration&& that) noexcept : declaration{ static_cast(that) }{} -#line 639 "reflect.h2" +#line 648 "reflect.h2" //----------------------------------------------------------------------- // Parameter declarations // -#line 646 "reflect.h2" +#line 655 "reflect.h2" parameter_declaration::parameter_declaration( parameter_declaration_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 651 "reflect.h2" +#line 660 "reflect.h2" { } -#line 655 "reflect.h2" +#line 664 "reflect.h2" [[nodiscard]] auto parameter_declaration::get_declaration() const& -> object_declaration { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).declaration), (*this) }; } -#line 656 "reflect.h2" +#line 665 "reflect.h2" [[nodiscard]] auto parameter_declaration::get_passing_style() const& -> passing_style { return (*cpp2::impl::assert_not_null(n)).pass; } -#line 658 "reflect.h2" +#line 667 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_implicit() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::implicit; } -#line 659 "reflect.h2" +#line 668 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_virtual() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::virtual_; } -#line 660 "reflect.h2" +#line 669 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_override() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::override_; } -#line 661 "reflect.h2" +#line 670 "reflect.h2" [[nodiscard]] auto parameter_declaration::is_final() const& -> bool { return (*cpp2::impl::assert_not_null(n)).mod == parameter_declaration_node::modifier::final_; } parameter_declaration::parameter_declaration(parameter_declaration const& that) @@ -3816,7 +3825,7 @@ alias_declaration::alias_declaration(alias_declaration&& that) noexcept parameter_declaration::parameter_declaration(parameter_declaration&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 665 "reflect.h2" +#line 674 "reflect.h2" //----------------------------------------------------------------------- // // Expressions @@ -3828,45 +3837,45 @@ parameter_declaration::parameter_declaration(parameter_declaration&& that) noexc // Binary expressions // -#line 692 "reflect.h2" +#line 701 "reflect.h2" template binary_expression::binary_expression( binary_expression_node* n_, cpp2::impl::in s ) : reflection_base>{ n_, s } -#line 697 "reflect.h2" +#line 706 "reflect.h2" { } -#line 701 "reflect.h2" +#line 710 "reflect.h2" template [[nodiscard]] auto binary_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 702 "reflect.h2" +#line 711 "reflect.h2" template [[nodiscard]] auto binary_expression::lhs_is_id_expression() const& -> bool { return CPP2_UFCS(lhs_is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 703 "reflect.h2" +#line 712 "reflect.h2" template [[nodiscard]] auto binary_expression::is_standalone_expression() const& -> bool { return CPP2_UFCS(is_standalone_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 704 "reflect.h2" +#line 713 "reflect.h2" template [[nodiscard]] auto binary_expression::terms_size() const& -> int { return CPP2_UFCS(terms_size)((*cpp2::impl::assert_not_null((*this).n))); } -#line 705 "reflect.h2" +#line 714 "reflect.h2" template [[nodiscard]] auto binary_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null((*this).n))); } -#line 706 "reflect.h2" +#line 715 "reflect.h2" template [[nodiscard]] auto binary_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 707 "reflect.h2" +#line 716 "reflect.h2" template [[nodiscard]] auto binary_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 708 "reflect.h2" +#line 717 "reflect.h2" template [[nodiscard]] auto binary_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null((*this).n))); } -#line 709 "reflect.h2" +#line 718 "reflect.h2" template [[nodiscard]] auto binary_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null((*this).n))); } -#line 715 "reflect.h2" +#line 724 "reflect.h2" template template binary_expression::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , term{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 717 "reflect.h2" +#line 726 "reflect.h2" template template [[nodiscard]] auto binary_expression::term_t::get_op() const& -> std::string { return op; } -#line 718 "reflect.h2" +#line 727 "reflect.h2" template template [[nodiscard]] auto binary_expression::term_t::get_term() const& -> T { return term; } template template binary_expression::term_t::term_t(term_t const& that) @@ -3884,7 +3893,7 @@ template template auto binary_expressi op = std::move(that).op; term = std::move(that).term; return *this;} -#line 721 "reflect.h2" +#line 730 "reflect.h2" template [[nodiscard]] auto binary_expression::get_terms() const& -> auto{ if constexpr (std::is_same_v) { std::vector> ret {}; @@ -3960,25 +3969,25 @@ template template auto binary_expressi } } -#line 796 "reflect.h2" +#line 805 "reflect.h2" template [[nodiscard]] auto binary_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 797 "reflect.h2" +#line 806 "reflect.h2" template [[nodiscard]] auto binary_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null((*this).n))))); } // Get the postfix-expression, if that's the entire expression (not actually binary) -#line 800 "reflect.h2" +#line 809 "reflect.h2" template [[nodiscard]] auto binary_expression::get_if_only_a_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_if_only_a_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } // Get left-hand postfix-expression -#line 802 "reflect.h2" +#line 811 "reflect.h2" template [[nodiscard]] auto binary_expression::get_lhs_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } // Get first right-hand postfix-expression, if there is one -#line 804 "reflect.h2" +#line 813 "reflect.h2" template [[nodiscard]] auto binary_expression::get_second_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_second_postfix_expression_node)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 806 "reflect.h2" +#line 815 "reflect.h2" template [[nodiscard]] auto binary_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null((*this).n))); } -#line 808 "reflect.h2" +#line 817 "reflect.h2" template [[nodiscard]] auto binary_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } template binary_expression::binary_expression(binary_expression const& that) @@ -3986,29 +3995,29 @@ template template auto binary_expressi template binary_expression::binary_expression(binary_expression&& that) noexcept : reflection_base>{ static_cast>&&>(that) }{} -#line 812 "reflect.h2" +#line 821 "reflect.h2" //----------------------------------------------------------------------- // Expression list // -#line 819 "reflect.h2" +#line 828 "reflect.h2" expression_list::expression_list( expression_list_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 824 "reflect.h2" +#line 833 "reflect.h2" { } -#line 828 "reflect.h2" +#line 837 "reflect.h2" [[nodiscard]] auto expression_list::is_empty() const& -> bool { return CPP2_UFCS(is_empty)((*cpp2::impl::assert_not_null(n))); } -#line 829 "reflect.h2" +#line 838 "reflect.h2" [[nodiscard]] auto expression_list::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 831 "reflect.h2" +#line 840 "reflect.h2" [[nodiscard]] auto expression_list::get_expressions() const& -> std::vector { @@ -4019,7 +4028,7 @@ template binary_expression::binary_expre return ret; } -#line 841 "reflect.h2" +#line 850 "reflect.h2" [[nodiscard]] auto expression_list::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression_list::expression_list(expression_list const& that) @@ -4027,24 +4036,24 @@ template binary_expression::binary_expre expression_list::expression_list(expression_list&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 845 "reflect.h2" +#line 854 "reflect.h2" //----------------------------------------------------------------------- // Prefix expressions // -#line 852 "reflect.h2" +#line 861 "reflect.h2" prefix_expression::prefix_expression( prefix_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 857 "reflect.h2" +#line 866 "reflect.h2" { } -#line 861 "reflect.h2" +#line 870 "reflect.h2" [[nodiscard]] auto prefix_expression::get_ops() const& -> std::vector{ std::vector ret {}; for ( auto const& op : (*cpp2::impl::assert_not_null(n)).ops ) { @@ -4053,32 +4062,32 @@ expression_list::expression_list(expression_list&& that) noexcept return ret; } -#line 869 "reflect.h2" +#line 878 "reflect.h2" [[nodiscard]] auto prefix_expression::get_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null((*this).n)).expr), (*this) }; } -#line 871 "reflect.h2" +#line 880 "reflect.h2" [[nodiscard]] auto prefix_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 872 "reflect.h2" +#line 881 "reflect.h2" [[nodiscard]] auto prefix_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 873 "reflect.h2" +#line 882 "reflect.h2" [[nodiscard]] auto prefix_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 874 "reflect.h2" +#line 883 "reflect.h2" [[nodiscard]] auto prefix_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 875 "reflect.h2" +#line 884 "reflect.h2" [[nodiscard]] auto prefix_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 876 "reflect.h2" +#line 885 "reflect.h2" [[nodiscard]] auto prefix_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 877 "reflect.h2" +#line 886 "reflect.h2" [[nodiscard]] auto prefix_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null(n))); } -#line 879 "reflect.h2" +#line 888 "reflect.h2" [[nodiscard]] auto prefix_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 880 "reflect.h2" +#line 889 "reflect.h2" [[nodiscard]] auto prefix_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 881 "reflect.h2" +#line 890 "reflect.h2" [[nodiscard]] auto prefix_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 883 "reflect.h2" +#line 892 "reflect.h2" [[nodiscard]] auto prefix_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } prefix_expression::~prefix_expression() noexcept{} @@ -4087,32 +4096,32 @@ prefix_expression::prefix_expression(prefix_expression const& that) prefix_expression::prefix_expression(prefix_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 887 "reflect.h2" +#line 896 "reflect.h2" //----------------------------------------------------------------------- // Postfix expressions // -#line 894 "reflect.h2" +#line 903 "reflect.h2" postfix_expression::postfix_expression( postfix_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 899 "reflect.h2" +#line 908 "reflect.h2" { } -#line 903 "reflect.h2" +#line 912 "reflect.h2" [[nodiscard]] auto postfix_expression::get_primary_expression() const& -> primary_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null((*this).n)).expr), (*this) }; } -#line 909 "reflect.h2" +#line 918 "reflect.h2" postfix_expression::term_t::term_t(auto&& term, auto&& cs) : term_{ CPP2_FORWARD(term) } , cs_{ CPP2_FORWARD(cs) }{} -#line 911 "reflect.h2" +#line 920 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_op() const& -> std::string_view { return CPP2_UFCS(as_string_view)((*cpp2::impl::assert_not_null((*cpp2::impl::assert_not_null(term_)).op))); } // If op is More is contained in the Notes @@ -4121,18 +4130,18 @@ prefix_expression::prefix_expression(prefix_expression&& that) noexcept // [ ( expression_list subscript or function call // ... expression fold expression -#line 919 "reflect.h2" +#line 928 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_id_expression() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).id_expr) != nullptr; } -#line 920 "reflect.h2" +#line 929 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_expression_list() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).expr_list) != nullptr; } -#line 921 "reflect.h2" +#line 930 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::is_expression() const& -> bool { return CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).last_expr) != nullptr; } -#line 923 "reflect.h2" +#line 932 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_id_expression() const& -> id_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).id_expr), *cpp2::impl::assert_not_null(cs_) }; } -#line 924 "reflect.h2" +#line 933 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_expression_list() const& -> expression_list { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).expr_list), *cpp2::impl::assert_not_null(cs_) }; } -#line 925 "reflect.h2" +#line 934 "reflect.h2" [[nodiscard]] auto postfix_expression::term_t::get_expression() const& -> expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(term_)).last_expr), *cpp2::impl::assert_not_null(cs_) }; } postfix_expression::term_t::term_t(term_t const& that) @@ -4142,46 +4151,46 @@ postfix_expression::term_t::term_t(term_t&& that) noexcept : term_{ std::move(that).term_ } , cs_{ std::move(that).cs_ }{} -#line 928 "reflect.h2" +#line 937 "reflect.h2" [[nodiscard]] auto postfix_expression::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ops ) {static_cast(CPP2_UFCS(emplace_back)(ret, &t, &(*this))); } return ret; } -#line 934 "reflect.h2" +#line 943 "reflect.h2" [[nodiscard]] auto postfix_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 935 "reflect.h2" +#line 944 "reflect.h2" [[nodiscard]] auto postfix_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 936 "reflect.h2" +#line 945 "reflect.h2" [[nodiscard]] auto postfix_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 937 "reflect.h2" +#line 946 "reflect.h2" [[nodiscard]] auto postfix_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 938 "reflect.h2" +#line 947 "reflect.h2" [[nodiscard]] auto postfix_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 939 "reflect.h2" +#line 948 "reflect.h2" [[nodiscard]] auto postfix_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 941 "reflect.h2" +#line 950 "reflect.h2" [[nodiscard]] auto postfix_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 942 "reflect.h2" +#line 951 "reflect.h2" [[nodiscard]] auto postfix_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 943 "reflect.h2" +#line 952 "reflect.h2" [[nodiscard]] auto postfix_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 945 "reflect.h2" +#line 954 "reflect.h2" [[nodiscard]] auto postfix_expression::get_first_token_ignoring_this() const& -> std::string_view{ auto ptok {CPP2_UFCS(get_first_token_ignoring_this)((*cpp2::impl::assert_not_null(n)))}; if (ptok) {return *cpp2::impl::assert_not_null(cpp2::move(ptok)); } return ""; } -#line 951 "reflect.h2" +#line 960 "reflect.h2" [[nodiscard]] auto postfix_expression::starts_with_function_call_with_num_parameters(cpp2::impl::in num) const& -> bool { return CPP2_UFCS(starts_with_function_call_with_n_parameters)((*cpp2::impl::assert_not_null(n)), num); } -#line 952 "reflect.h2" +#line 961 "reflect.h2" [[nodiscard]] auto postfix_expression::is_result_a_temporary_variable() const& -> bool { return CPP2_UFCS(is_result_a_temporary_variable)((*cpp2::impl::assert_not_null(n))); } -#line 954 "reflect.h2" +#line 963 "reflect.h2" [[nodiscard]] auto postfix_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } postfix_expression::postfix_expression(postfix_expression const& that) @@ -4189,34 +4198,34 @@ postfix_expression::term_t::term_t(term_t&& that) noexcept postfix_expression::postfix_expression(postfix_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 958 "reflect.h2" +#line 967 "reflect.h2" //----------------------------------------------------------------------- // Template arguments // -#line 965 "reflect.h2" +#line 974 "reflect.h2" template_arg::template_arg( template_argument* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 970 "reflect.h2" +#line 979 "reflect.h2" { } -#line 974 "reflect.h2" +#line 983 "reflect.h2" [[nodiscard]] auto template_arg::is_expression() const& -> bool { return CPP2_UFCS(is_expression)((*cpp2::impl::assert_not_null(n))); } -#line 975 "reflect.h2" +#line 984 "reflect.h2" [[nodiscard]] auto template_arg::is_type_id() const& -> bool { return CPP2_UFCS(is_type_id)((*cpp2::impl::assert_not_null(n))); } -#line 977 "reflect.h2" +#line 986 "reflect.h2" [[nodiscard]] auto template_arg::as_expression() const& -> expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 978 "reflect.h2" +#line 987 "reflect.h2" [[nodiscard]] auto template_arg::as_type_id() const& -> type_id { return { CPP2_UFCS(get_type_id)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 980 "reflect.h2" +#line 989 "reflect.h2" [[nodiscard]] auto template_arg::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } template_arg::template_arg(template_arg const& that) @@ -4224,27 +4233,27 @@ postfix_expression::postfix_expression(postfix_expression&& that) noexcept template_arg::template_arg(template_arg&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 984 "reflect.h2" +#line 993 "reflect.h2" //----------------------------------------------------------------------- // Unqualified IDs // -#line 991 "reflect.h2" +#line 1000 "reflect.h2" unqualified_id::unqualified_id( unqualified_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 996 "reflect.h2" +#line 1005 "reflect.h2" { } -#line 1000 "reflect.h2" +#line 1009 "reflect.h2" [[nodiscard]] auto unqualified_id::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1002 "reflect.h2" +#line 1011 "reflect.h2" [[nodiscard]] auto unqualified_id::get_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } //get_template_args: (this) -> std::vector = { @@ -4253,10 +4262,10 @@ template_arg::template_arg(template_arg&& that) noexcept // return ret; //} -#line 1010 "reflect.h2" +#line 1019 "reflect.h2" [[nodiscard]] auto unqualified_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1012 "reflect.h2" +#line 1021 "reflect.h2" [[nodiscard]] auto unqualified_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } unqualified_id::unqualified_id(unqualified_id const& that) @@ -4264,31 +4273,31 @@ template_arg::template_arg(template_arg&& that) noexcept unqualified_id::unqualified_id(unqualified_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1016 "reflect.h2" +#line 1025 "reflect.h2" //----------------------------------------------------------------------- // Qualified IDs // -#line 1023 "reflect.h2" +#line 1032 "reflect.h2" qualified_id::qualified_id( qualified_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1028 "reflect.h2" +#line 1037 "reflect.h2" { } -#line 1036 "reflect.h2" +#line 1045 "reflect.h2" qualified_id::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , unqualified{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 1038 "reflect.h2" +#line 1047 "reflect.h2" [[nodiscard]] auto qualified_id::term_t::get_op() const& -> std::string { return op; } -#line 1039 "reflect.h2" +#line 1048 "reflect.h2" [[nodiscard]] auto qualified_id::term_t::get_unqualified() const& -> unqualified_id { return unqualified; } qualified_id::term_t::term_t(term_t const& that) @@ -4298,7 +4307,7 @@ qualified_id::term_t::term_t(term_t&& that) noexcept : op{ std::move(that).op } , unqualified{ std::move(that).unqualified }{} -#line 1042 "reflect.h2" +#line 1051 "reflect.h2" [[nodiscard]] auto qualified_id::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ids ) {static_cast(CPP2_UFCS(emplace_back)(ret, *cpp2::impl::assert_not_null(t.scope_op), CPP2_UFCS(get)(t.id), (*this))); } @@ -4311,10 +4320,10 @@ qualified_id::term_t::term_t(term_t&& that) noexcept // return ret; //} -#line 1054 "reflect.h2" +#line 1063 "reflect.h2" [[nodiscard]] auto qualified_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1056 "reflect.h2" +#line 1065 "reflect.h2" [[nodiscard]] auto qualified_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } qualified_id::qualified_id(qualified_id const& that) @@ -4322,19 +4331,19 @@ qualified_id::term_t::term_t(term_t&& that) noexcept qualified_id::qualified_id(qualified_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1060 "reflect.h2" +#line 1069 "reflect.h2" //----------------------------------------------------------------------- // Type IDs // -#line 1067 "reflect.h2" +#line 1076 "reflect.h2" type_id::type_id( type_id_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1072 "reflect.h2" +#line 1081 "reflect.h2" { } @@ -4345,37 +4354,37 @@ qualified_id::qualified_id(qualified_id&& that) noexcept // return ret; //} -#line 1082 "reflect.h2" +#line 1091 "reflect.h2" [[nodiscard]] auto type_id::is_postfix_expression() const& -> bool { return CPP2_UFCS(is_postfix_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1083 "reflect.h2" +#line 1092 "reflect.h2" [[nodiscard]] auto type_id::is_qualified_id() const& -> bool { return CPP2_UFCS(is_qualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1084 "reflect.h2" +#line 1093 "reflect.h2" [[nodiscard]] auto type_id::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1085 "reflect.h2" +#line 1094 "reflect.h2" [[nodiscard]] auto type_id::is_function_typeid() const& -> bool { return CPP2_UFCS(is_function_typeid)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1086 "reflect.h2" +#line 1095 "reflect.h2" [[nodiscard]] auto type_id::is_keyword() const& -> bool { return CPP2_UFCS(is_keyword)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1087 "reflect.h2" +#line 1096 "reflect.h2" [[nodiscard]] auto type_id::is_wildcard() const& -> bool { return CPP2_UFCS(is_wildcard)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1088 "reflect.h2" +#line 1097 "reflect.h2" [[nodiscard]] auto type_id::is_pointer_qualified() const& -> bool { return CPP2_UFCS(is_pointer_qualified)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1089 "reflect.h2" +#line 1098 "reflect.h2" [[nodiscard]] auto type_id::is_concept() const& -> bool { return CPP2_UFCS(is_concept)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1091 "reflect.h2" +#line 1100 "reflect.h2" [[nodiscard]] auto type_id::as_postfix_expression() const& -> postfix_expression { return { CPP2_UFCS(get_postfix_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1092 "reflect.h2" +#line 1101 "reflect.h2" [[nodiscard]] auto type_id::as_qualified_id() const& -> qualified_id { return { CPP2_UFCS(get_qualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1093 "reflect.h2" +#line 1102 "reflect.h2" [[nodiscard]] auto type_id::as_unqualified_id() const& -> unqualified_id { return { CPP2_UFCS(get_unqualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } // TODO //as_function_typeid : (this) -> function_typeid = (n*.get_function_typeid(), this); -#line 1096 "reflect.h2" +#line 1105 "reflect.h2" [[nodiscard]] auto type_id::as_keyword() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_keyword)(*cpp2::impl::assert_not_null(n))))); } -#line 1097 "reflect.h2" +#line 1106 "reflect.h2" [[nodiscard]] auto type_id::as_token() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_token)(*cpp2::impl::assert_not_null(n))))); } -#line 1099 "reflect.h2" +#line 1108 "reflect.h2" [[nodiscard]] auto type_id::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } type_id::type_id(type_id const& that) @@ -4383,19 +4392,19 @@ qualified_id::qualified_id(qualified_id&& that) noexcept type_id::type_id(type_id&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1103 "reflect.h2" +#line 1112 "reflect.h2" //----------------------------------------------------------------------- // Primary expressions // -#line 1110 "reflect.h2" +#line 1119 "reflect.h2" primary_expression::primary_expression( primary_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1115 "reflect.h2" +#line 1124 "reflect.h2" { } @@ -4406,31 +4415,31 @@ type_id::type_id(type_id&& that) noexcept // return ret; //} -#line 1125 "reflect.h2" +#line 1134 "reflect.h2" [[nodiscard]] auto primary_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1126 "reflect.h2" +#line 1135 "reflect.h2" [[nodiscard]] auto primary_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1127 "reflect.h2" +#line 1136 "reflect.h2" [[nodiscard]] auto primary_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1128 "reflect.h2" +#line 1137 "reflect.h2" [[nodiscard]] auto primary_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 1129 "reflect.h2" +#line 1138 "reflect.h2" [[nodiscard]] auto primary_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1130 "reflect.h2" +#line 1139 "reflect.h2" [[nodiscard]] auto primary_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 1131 "reflect.h2" +#line 1140 "reflect.h2" [[nodiscard]] auto primary_expression::is_declaration() const& -> bool { return CPP2_UFCS(is_declaration)((*cpp2::impl::assert_not_null(n))); } -#line 1133 "reflect.h2" +#line 1142 "reflect.h2" [[nodiscard]] auto primary_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1134 "reflect.h2" +#line 1143 "reflect.h2" [[nodiscard]] auto primary_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1135 "reflect.h2" +#line 1144 "reflect.h2" [[nodiscard]] auto primary_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1136 "reflect.h2" +#line 1145 "reflect.h2" [[nodiscard]] auto primary_expression::as_declaration() const& -> declaration { return { CPP2_UFCS(get_declaration)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1138 "reflect.h2" +#line 1147 "reflect.h2" [[nodiscard]] auto primary_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } primary_expression::primary_expression(primary_expression const& that) @@ -4438,19 +4447,19 @@ type_id::type_id(type_id&& that) noexcept primary_expression::primary_expression(primary_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1142 "reflect.h2" +#line 1151 "reflect.h2" //----------------------------------------------------------------------- // ID expression // -#line 1149 "reflect.h2" +#line 1158 "reflect.h2" id_expression::id_expression( id_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1154 "reflect.h2" +#line 1163 "reflect.h2" { } @@ -4461,25 +4470,25 @@ primary_expression::primary_expression(primary_expression&& that) noexcept // return ret; //} -#line 1164 "reflect.h2" +#line 1173 "reflect.h2" [[nodiscard]] auto id_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1165 "reflect.h2" +#line 1174 "reflect.h2" [[nodiscard]] auto id_expression::is_empty() const& -> bool { return CPP2_UFCS(is_empty)((*cpp2::impl::assert_not_null(n))); } -#line 1166 "reflect.h2" +#line 1175 "reflect.h2" [[nodiscard]] auto id_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1167 "reflect.h2" +#line 1176 "reflect.h2" [[nodiscard]] auto id_expression::is_qualified() const& -> bool { return CPP2_UFCS(is_qualified)((*cpp2::impl::assert_not_null(n))); } -#line 1168 "reflect.h2" +#line 1177 "reflect.h2" [[nodiscard]] auto id_expression::is_unqualified() const& -> bool { return CPP2_UFCS(is_unqualified)((*cpp2::impl::assert_not_null(n))); } -#line 1170 "reflect.h2" +#line 1179 "reflect.h2" [[nodiscard]] auto id_expression::as_identifier() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1171 "reflect.h2" +#line 1180 "reflect.h2" [[nodiscard]] auto id_expression::as_qualified() const& -> qualified_id { return { CPP2_UFCS(get_qualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1172 "reflect.h2" +#line 1181 "reflect.h2" [[nodiscard]] auto id_expression::as_unqualified() const& -> unqualified_id { return { CPP2_UFCS(get_unqualified_id)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1174 "reflect.h2" +#line 1183 "reflect.h2" [[nodiscard]] auto id_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } id_expression::~id_expression() noexcept{} @@ -4488,71 +4497,71 @@ id_expression::id_expression(id_expression const& that) id_expression::id_expression(id_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1178 "reflect.h2" +#line 1187 "reflect.h2" //----------------------------------------------------------------------- // General expression // -#line 1185 "reflect.h2" +#line 1194 "reflect.h2" expression::expression( expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1190 "reflect.h2" +#line 1199 "reflect.h2" { } -#line 1194 "reflect.h2" +#line 1203 "reflect.h2" [[nodiscard]] auto expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1195 "reflect.h2" +#line 1204 "reflect.h2" [[nodiscard]] auto expression::is_standalone_expression() const& -> bool { return CPP2_UFCS(is_standalone_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1196 "reflect.h2" +#line 1205 "reflect.h2" [[nodiscard]] auto expression::subexpression_count() const& -> int { return CPP2_UFCS(subexpression_count)((*cpp2::impl::assert_not_null(n))); } -#line 1197 "reflect.h2" +#line 1206 "reflect.h2" [[nodiscard]] auto expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null(n))); } -#line 1198 "reflect.h2" +#line 1207 "reflect.h2" [[nodiscard]] auto expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1199 "reflect.h2" +#line 1208 "reflect.h2" [[nodiscard]] auto expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null(n))); } -#line 1200 "reflect.h2" +#line 1209 "reflect.h2" [[nodiscard]] auto expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1201 "reflect.h2" +#line 1210 "reflect.h2" [[nodiscard]] auto expression::is_empty_expression_list() const& -> bool { return CPP2_UFCS(is_empty_expression_list)((*cpp2::impl::assert_not_null(n))); } -#line 1202 "reflect.h2" +#line 1211 "reflect.h2" [[nodiscard]] auto expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null(n))); } -#line 1203 "reflect.h2" +#line 1212 "reflect.h2" [[nodiscard]] auto expression::is_assignment_expression() const& -> bool { return CPP2_UFCS(is_assignment_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1205 "reflect.h2" +#line 1214 "reflect.h2" [[nodiscard]] auto expression::is_simple_assignment() const& -> bool{ auto ret {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)((*cpp2::impl::assert_not_null(n)))}; return ret.lhs && ret.rhs; } -#line 1210 "reflect.h2" +#line 1219 "reflect.h2" [[nodiscard]] auto expression::get_lhs_rhs_if_simple_assignment() const& -> get_lhs_rhs_if_simple_assignment_ret -#line 1215 "reflect.h2" +#line 1224 "reflect.h2" { cpp2::impl::deferred_init lhs; cpp2::impl::deferred_init rhs; -#line 1216 "reflect.h2" +#line 1225 "reflect.h2" auto ret {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)((*cpp2::impl::assert_not_null(n)))}; lhs.construct(ret.lhs, (*this)); rhs.construct(cpp2::move(ret).rhs, (*this)); return { std::move(lhs.value()), std::move(rhs.value()) }; } -#line 1221 "reflect.h2" +#line 1230 "reflect.h2" [[nodiscard]] auto expression::as_assignment_expression() const& -> assignment_expression { return { CPP2_UFCS(get_assignment_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1222 "reflect.h2" +#line 1231 "reflect.h2" [[nodiscard]] auto expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1223 "reflect.h2" +#line 1232 "reflect.h2" [[nodiscard]] auto expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1225 "reflect.h2" +#line 1234 "reflect.h2" [[nodiscard]] auto expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression::~expression() noexcept{} @@ -4561,31 +4570,31 @@ expression::expression(expression const& that) expression::expression(expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1229 "reflect.h2" +#line 1238 "reflect.h2" //----------------------------------------------------------------------- // is_as_expression // -#line 1236 "reflect.h2" +#line 1245 "reflect.h2" is_as_expression::is_as_expression( is_as_expression_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1241 "reflect.h2" +#line 1250 "reflect.h2" { } -#line 1249 "reflect.h2" +#line 1258 "reflect.h2" is_as_expression::term_t::term_t(auto&& o, auto&& ptr, auto&& cs) : op{ CPP2_FORWARD(o) } , expr{ CPP2_FORWARD(ptr), CPP2_FORWARD(cs) }{} -#line 1251 "reflect.h2" +#line 1260 "reflect.h2" [[nodiscard]] auto is_as_expression::term_t::get_op() const& -> std::string { return op; } -#line 1252 "reflect.h2" +#line 1261 "reflect.h2" [[nodiscard]] auto is_as_expression::term_t::get_expr() const& -> expression { return expr; } is_as_expression::term_t::term_t(term_t const& that) @@ -4595,42 +4604,42 @@ is_as_expression::term_t::term_t(term_t&& that) noexcept : op{ std::move(that).op } , expr{ std::move(that).expr }{} -#line 1255 "reflect.h2" +#line 1264 "reflect.h2" [[nodiscard]] auto is_as_expression::get_expression() const& -> prefix_expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).expr), (*this) }; } -#line 1257 "reflect.h2" +#line 1266 "reflect.h2" [[nodiscard]] auto is_as_expression::get_terms() const& -> auto{ std::vector ret {}; for ( auto const& t : (*cpp2::impl::assert_not_null((*this).n)).ops ) {static_cast(CPP2_UFCS(emplace_back)(ret, *cpp2::impl::assert_not_null(t.op), CPP2_UFCS(get)(t.expr), (*this))); } return ret; } -#line 1263 "reflect.h2" +#line 1272 "reflect.h2" [[nodiscard]] auto is_as_expression::is_fold_expression() const& -> bool { return CPP2_UFCS(is_fold_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1264 "reflect.h2" +#line 1273 "reflect.h2" [[nodiscard]] auto is_as_expression::is_identifier() const& -> bool { return CPP2_UFCS(is_identifier)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1265 "reflect.h2" +#line 1274 "reflect.h2" [[nodiscard]] auto is_as_expression::is_id_expression() const& -> bool { return CPP2_UFCS(is_id_expression)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1266 "reflect.h2" +#line 1275 "reflect.h2" [[nodiscard]] auto is_as_expression::is_unqualified_id() const& -> bool { return CPP2_UFCS(is_unqualified_id)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1267 "reflect.h2" +#line 1276 "reflect.h2" [[nodiscard]] auto is_as_expression::is_expression_list() const& -> bool { return CPP2_UFCS(is_expression_list)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1268 "reflect.h2" +#line 1277 "reflect.h2" [[nodiscard]] auto is_as_expression::is_literal() const& -> bool { return CPP2_UFCS(is_literal)((*cpp2::impl::assert_not_null((*this).n))); } -#line 1270 "reflect.h2" +#line 1279 "reflect.h2" [[nodiscard]] auto is_as_expression::as_expression_list() const& -> expression_list { return { CPP2_UFCS(get_expression_list)((*cpp2::impl::assert_not_null((*this).n))), (*this) }; } -#line 1271 "reflect.h2" +#line 1280 "reflect.h2" [[nodiscard]] auto is_as_expression::as_literal() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_literal)(*cpp2::impl::assert_not_null(n))))); } -#line 1273 "reflect.h2" +#line 1282 "reflect.h2" [[nodiscard]] auto is_as_expression::get_identifier() const& -> std::string_view{ auto ptok {CPP2_UFCS(get_identifier)((*cpp2::impl::assert_not_null((*this).n)))}; if (ptok) {return *cpp2::impl::assert_not_null(cpp2::move(ptok)); } return ""; } -#line 1279 "reflect.h2" +#line 1288 "reflect.h2" [[nodiscard]] auto is_as_expression::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null((*this).n))); } is_as_expression::~is_as_expression() noexcept{} @@ -4639,7 +4648,7 @@ is_as_expression::is_as_expression(is_as_expression const& that) is_as_expression::is_as_expression(is_as_expression&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1283 "reflect.h2" +#line 1292 "reflect.h2" //----------------------------------------------------------------------- // // Statements @@ -4651,57 +4660,57 @@ is_as_expression::is_as_expression(is_as_expression&& that) noexcept // General statement // -#line 1297 "reflect.h2" +#line 1306 "reflect.h2" statement::statement( statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1302 "reflect.h2" +#line 1311 "reflect.h2" { } -#line 1306 "reflect.h2" +#line 1315 "reflect.h2" [[nodiscard]] auto statement::is_expression_statement() const& -> bool { return CPP2_UFCS(is_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1307 "reflect.h2" +#line 1316 "reflect.h2" [[nodiscard]] auto statement::is_compound_statement() const& -> bool { return CPP2_UFCS(is_compound)((*cpp2::impl::assert_not_null(n))); } -#line 1308 "reflect.h2" +#line 1317 "reflect.h2" [[nodiscard]] auto statement::is_selection_statement() const& -> bool { return CPP2_UFCS(is_selection)((*cpp2::impl::assert_not_null(n))); } -#line 1309 "reflect.h2" +#line 1318 "reflect.h2" [[nodiscard]] auto statement::is_declaration() const& -> bool { return CPP2_UFCS(is_declaration)((*cpp2::impl::assert_not_null(n))); } -#line 1310 "reflect.h2" +#line 1319 "reflect.h2" [[nodiscard]] auto statement::is_return_statement() const& -> bool { return CPP2_UFCS(is_return)((*cpp2::impl::assert_not_null(n))); } -#line 1311 "reflect.h2" +#line 1320 "reflect.h2" [[nodiscard]] auto statement::is_iteration_statement() const& -> bool { return CPP2_UFCS(is_iteration)((*cpp2::impl::assert_not_null(n))); } -#line 1312 "reflect.h2" +#line 1321 "reflect.h2" [[nodiscard]] auto statement::is_using_statement() const& -> bool { return CPP2_UFCS(is_using)((*cpp2::impl::assert_not_null(n))); } -#line 1313 "reflect.h2" +#line 1322 "reflect.h2" [[nodiscard]] auto statement::is_contract() const& -> bool { return CPP2_UFCS(is_contract)((*cpp2::impl::assert_not_null(n))); } -#line 1314 "reflect.h2" +#line 1323 "reflect.h2" [[nodiscard]] auto statement::is_inspect_expression() const& -> bool { return CPP2_UFCS(is_inspect)((*cpp2::impl::assert_not_null(n))); } -#line 1315 "reflect.h2" +#line 1324 "reflect.h2" [[nodiscard]] auto statement::is_jump_statement() const& -> bool { return CPP2_UFCS(is_jump)((*cpp2::impl::assert_not_null(n))); } -#line 1317 "reflect.h2" +#line 1326 "reflect.h2" [[nodiscard]] auto statement::as_expression_statement() const& -> expression_statement { return { CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1318 "reflect.h2" +#line 1327 "reflect.h2" [[nodiscard]] auto statement::as_compound_statement() const& -> compound_statement { return { CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1319 "reflect.h2" +#line 1328 "reflect.h2" [[nodiscard]] auto statement::as_selection_statement() const& -> selection_statement { return selection_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1320 "reflect.h2" +#line 1329 "reflect.h2" [[nodiscard]] auto statement::as_declaration() const& -> declaration { return declaration(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1321 "reflect.h2" +#line 1330 "reflect.h2" [[nodiscard]] auto statement::as_return_statement() const& -> return_statement { return return_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } -#line 1322 "reflect.h2" +#line 1331 "reflect.h2" [[nodiscard]] auto statement::as_iteration_statement() const& -> iteration_statement { return iteration_statement(CPP2_UFCS_TEMPLATE(get_if)((*cpp2::impl::assert_not_null(n))), (*this)); } //as_using_statement : (this) -> using_statement = using_statement (n*.get_if(), this); //as_contract : (this) -> contract = contract (n*.get_if(), this); //as_inspect_expression : (this) -> inspect_expression = inspect_expression (n*.get_if(), this); //as_jump_statement : (this) -> jump_statement = jump_statement (n*.get_if(), this); -#line 1328 "reflect.h2" +#line 1337 "reflect.h2" [[nodiscard]] auto statement::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } statement::~statement() noexcept{} @@ -4710,27 +4719,27 @@ statement::statement(statement const& that) statement::statement(statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1332 "reflect.h2" +#line 1341 "reflect.h2" //----------------------------------------------------------------------- // Expression statements // -#line 1339 "reflect.h2" +#line 1348 "reflect.h2" expression_statement::expression_statement( expression_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1344 "reflect.h2" +#line 1353 "reflect.h2" { } -#line 1348 "reflect.h2" +#line 1357 "reflect.h2" [[nodiscard]] auto expression_statement::get_expression() const& -> expression { return { CPP2_UFCS(get)((*cpp2::impl::assert_not_null(n)).expr), (*this) }; } -#line 1350 "reflect.h2" +#line 1359 "reflect.h2" [[nodiscard]] auto expression_statement::to_string() const& -> std::string { return CPP2_UFCS(to_string)((*cpp2::impl::assert_not_null(n))); } expression_statement::expression_statement(expression_statement const& that) @@ -4738,24 +4747,24 @@ statement::statement(statement&& that) noexcept expression_statement::expression_statement(expression_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1354 "reflect.h2" +#line 1363 "reflect.h2" //----------------------------------------------------------------------- // Compound statements // -#line 1361 "reflect.h2" +#line 1370 "reflect.h2" compound_statement::compound_statement( compound_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1366 "reflect.h2" +#line 1375 "reflect.h2" { } -#line 1370 "reflect.h2" +#line 1379 "reflect.h2" [[nodiscard]] auto compound_statement::get_statements() const& -> std::vector { @@ -4766,7 +4775,7 @@ expression_statement::expression_statement(expression_statement&& that) noexcept return ret; } -#line 1380 "reflect.h2" +#line 1389 "reflect.h2" auto compound_statement::add_statement(cpp2::impl::in source, cpp2::impl::in before_position) & -> void { auto stmt {parse_statement(source)}; @@ -4783,35 +4792,35 @@ expression_statement::expression_statement(expression_statement&& that) noexcept compound_statement::compound_statement(compound_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1393 "reflect.h2" +#line 1402 "reflect.h2" //----------------------------------------------------------------------- // Selection statements // -#line 1400 "reflect.h2" +#line 1409 "reflect.h2" selection_statement::selection_statement( selection_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1405 "reflect.h2" +#line 1414 "reflect.h2" { } -#line 1409 "reflect.h2" +#line 1418 "reflect.h2" [[nodiscard]] auto selection_statement::has_false_branch_in_source_code() const& -> bool { return CPP2_UFCS(has_false_branch_in_source_code)((*cpp2::impl::assert_not_null(n))); } -#line 1410 "reflect.h2" +#line 1419 "reflect.h2" [[nodiscard]] auto selection_statement::has_false_branch() const& -> bool { return CPP2_UFCS(has_false_branch)((*cpp2::impl::assert_not_null(n))); } -#line 1412 "reflect.h2" +#line 1421 "reflect.h2" [[nodiscard]] auto selection_statement::get_identifier() const& -> std::string_view { return CPP2_UFCS(as_string_view)((*cpp2::impl::assert_not_null(CPP2_UFCS(get_identifier)(*cpp2::impl::assert_not_null(n))))); } -#line 1413 "reflect.h2" +#line 1422 "reflect.h2" [[nodiscard]] auto selection_statement::get_expression() const& -> logical_or_expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1414 "reflect.h2" +#line 1423 "reflect.h2" [[nodiscard]] auto selection_statement::get_true_branch() const& -> compound_statement { return { CPP2_UFCS(get_true_branch)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1415 "reflect.h2" +#line 1424 "reflect.h2" [[nodiscard]] auto selection_statement::get_false_branch() const& -> compound_statement { return { CPP2_UFCS(get_false_branch)((*cpp2::impl::assert_not_null(n))), (*this) }; } selection_statement::selection_statement(selection_statement const& that) @@ -4819,27 +4828,27 @@ compound_statement::compound_statement(compound_statement&& that) noexcept selection_statement::selection_statement(selection_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1419 "reflect.h2" +#line 1428 "reflect.h2" //----------------------------------------------------------------------- // Return statements // -#line 1426 "reflect.h2" +#line 1435 "reflect.h2" return_statement::return_statement( return_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1431 "reflect.h2" +#line 1440 "reflect.h2" { } -#line 1435 "reflect.h2" +#line 1444 "reflect.h2" [[nodiscard]] auto return_statement::has_expression() const& -> bool { return CPP2_UFCS(has_expression)((*cpp2::impl::assert_not_null(n))); } -#line 1437 "reflect.h2" +#line 1446 "reflect.h2" [[nodiscard]] auto return_statement::get_expression() const& -> expression { return { CPP2_UFCS(get_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } return_statement::return_statement(return_statement const& that) @@ -4847,45 +4856,45 @@ selection_statement::selection_statement(selection_statement&& that) noexcept return_statement::return_statement(return_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1441 "reflect.h2" +#line 1450 "reflect.h2" //----------------------------------------------------------------------- // Iteration statements - for, do, while // -#line 1448 "reflect.h2" +#line 1457 "reflect.h2" iteration_statement::iteration_statement( iteration_statement_node* n_, cpp2::impl::in s ) : reflection_base{ n_, s } -#line 1453 "reflect.h2" +#line 1462 "reflect.h2" { } -#line 1457 "reflect.h2" +#line 1466 "reflect.h2" [[nodiscard]] auto iteration_statement::is_do() const& -> bool { return CPP2_UFCS(is_do)((*cpp2::impl::assert_not_null(n))); } -#line 1458 "reflect.h2" +#line 1467 "reflect.h2" [[nodiscard]] auto iteration_statement::is_while() const& -> bool { return CPP2_UFCS(is_while)((*cpp2::impl::assert_not_null(n))); } -#line 1459 "reflect.h2" +#line 1468 "reflect.h2" [[nodiscard]] auto iteration_statement::is_for() const& -> bool { return CPP2_UFCS(is_for)((*cpp2::impl::assert_not_null(n))); } -#line 1460 "reflect.h2" +#line 1469 "reflect.h2" [[nodiscard]] auto iteration_statement::has_next() const& -> bool { return CPP2_UFCS(has_next)((*cpp2::impl::assert_not_null(n))); } -#line 1462 "reflect.h2" +#line 1471 "reflect.h2" [[nodiscard]] auto iteration_statement::get_label() const& -> std::string { return CPP2_UFCS(to_string)(CPP2_UFCS(get_label)((*cpp2::impl::assert_not_null(n)))); } -#line 1463 "reflect.h2" +#line 1472 "reflect.h2" [[nodiscard]] auto iteration_statement::get_next_expression() const& -> assignment_expression { return { CPP2_UFCS(get_next_expression)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1464 "reflect.h2" +#line 1473 "reflect.h2" [[nodiscard]] auto iteration_statement::get_do_while_condition() const& -> logical_or_expression { return { CPP2_UFCS(get_do_while_condition)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1465 "reflect.h2" +#line 1474 "reflect.h2" [[nodiscard]] auto iteration_statement::get_do_while_body() const& -> compound_statement { return { CPP2_UFCS(get_do_while_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1466 "reflect.h2" +#line 1475 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_range() const& -> expression { return { CPP2_UFCS(get_for_range)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1467 "reflect.h2" +#line 1476 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_parameter() const& -> parameter_declaration { return { CPP2_UFCS(get_for_parameter)((*cpp2::impl::assert_not_null(n))), (*this) }; } -#line 1468 "reflect.h2" +#line 1477 "reflect.h2" [[nodiscard]] auto iteration_statement::get_for_body() const& -> statement { return { CPP2_UFCS(get_for_body)((*cpp2::impl::assert_not_null(n))), (*this) }; } iteration_statement::iteration_statement(iteration_statement const& that) @@ -4893,7 +4902,7 @@ return_statement::return_statement(return_statement&& that) noexcept iteration_statement::iteration_statement(iteration_statement&& that) noexcept : reflection_base{ static_cast&&>(that) }{} -#line 1472 "reflect.h2" +#line 1481 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -4906,13 +4915,13 @@ iteration_statement::iteration_statement(iteration_statement&& that) noexcept // Some common metafunction helpers (metafunctions are just functions, // so they can be factored as usual) // -#line 1484 "reflect.h2" +#line 1493 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 1490 "reflect.h2" +#line 1499 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -4927,7 +4936,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void // a public default constructor, a public virtual destructor, and // protected copy/move operations // -#line 1504 "reflect.h2" +#line 1513 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -4959,7 +4968,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 1536 "reflect.h2" +#line 1545 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -4976,7 +4985,7 @@ auto interface(meta::type_declaration& t) -> void // // Unlike an interface, it can have nonpublic and nonvirtual functions. // -#line 1552 "reflect.h2" +#line 1561 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -5001,7 +5010,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 1577 "reflect.h2" +#line 1586 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -5022,7 +5031,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // -#line 1597 "reflect.h2" +#line 1606 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::impl::in ordering// must be "strong_ordering" etc. @@ -5052,7 +5061,7 @@ auto ordered_impl( // // Note: the ordering that should be encouraged as default gets the nice name // -#line 1626 "reflect.h2" +#line 1635 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); @@ -5061,7 +5070,7 @@ auto ordered(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // -#line 1634 "reflect.h2" +#line 1643 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); @@ -5070,13 +5079,13 @@ auto weakly_ordered(meta::type_declaration& t) -> void //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // -#line 1642 "reflect.h2" +#line 1651 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 1648 "reflect.h2" +#line 1657 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -5093,7 +5102,7 @@ auto partially_ordered(meta::type_declaration& t) -> void // // A type with (copy and move) x (construction and assignment) // -#line 1664 "reflect.h2" +#line 1673 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -5121,12 +5130,12 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 1692 "reflect.h2" +#line 1701 "reflect.h2" // copy_constructible // // A type with (copy and move) construction // -#line 1696 "reflect.h2" +#line 1705 "reflect.h2" auto copy_constructible(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move constructors, @@ -5152,14 +5161,14 @@ auto copy_constructible(meta::type_declaration& t) -> void }} } -#line 1722 "reflect.h2" +#line 1731 "reflect.h2" //----------------------------------------------------------------------- // // hashable // // A memberwise hashable type // -#line 1728 "reflect.h2" +#line 1737 "reflect.h2" auto hashable(meta::type_declaration& t) -> void { CPP2_UFCS(require)(t, !(CPP2_UFCS(empty)(CPP2_UFCS(get_member_objects)(t))), @@ -5185,7 +5194,7 @@ auto hashable(meta::type_declaration& t) -> void CPP2_UFCS(add_member)(t, cpp2::move(hash) + "\n return ret;\n }"); } -#line 1754 "reflect.h2" +#line 1763 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -5193,7 +5202,7 @@ auto hashable(meta::type_declaration& t) -> void // A regular type: copyable, plus has public default construction // and no protected or virtual functions // -#line 1761 "reflect.h2" +#line 1770 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -5222,28 +5231,28 @@ auto basic_value(meta::type_declaration& t) -> void // // Note: the ordering that should be encouraged as default gets the nice name // -#line 1789 "reflect.h2" +#line 1798 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1795 "reflect.h2" +#line 1804 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(weakly_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1801 "reflect.h2" +#line 1810 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(partially_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 1808 "reflect.h2" +#line 1817 "reflect.h2" //----------------------------------------------------------------------- // // C.20: If you can avoid defining default operations, do @@ -5266,7 +5275,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void // // a type without declared copy/move/destructor functions // -#line 1830 "reflect.h2" +#line 1839 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void { for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) @@ -5309,7 +5318,7 @@ auto cpp1_rule_of_zero(meta::type_declaration& t) -> void // parameters instead of concrete forwarding parameters (mainly used // for cppfront internal use, so cppfront builds under GCC 10) // -#line 1872 "reflect.h2" +#line 1881 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { std::string ctor_params {}; @@ -5366,7 +5375,7 @@ value_member_info::value_member_info(auto const& name_, auto const& type_, auto , type{ type_ } , value{ value_ }{} -#line 1924 "reflect.h2" +#line 1933 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -5385,7 +5394,7 @@ value_member_info::value_member_info(auto const& name_, auto const& type_, auto // a type together with named constants that are its possible values // -#line 1947 "reflect.h2" +#line 1956 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -5410,7 +5419,7 @@ auto basic_enum( { std::string value{"-1"}; -#line 1970 "reflect.h2" +#line 1979 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -5452,7 +5461,7 @@ std::string value{"-1"}; } } -#line 2010 "reflect.h2" +#line 2019 "reflect.h2" if ((CPP2_UFCS(empty)(enumerators))) { CPP2_UFCS(error)(t, "an enumeration must contain at least one enumerator value"); return ; @@ -5503,7 +5512,7 @@ std::string value{"-1"}; } } -#line 2061 "reflect.h2" +#line 2070 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents // // Note that most values and functions are declared as '==' compile-time values, i.e. Cpp1 'constexpr' @@ -5553,7 +5562,7 @@ std::string to_string_impl{" to_string_impl: (this, prefix: std::string_view" // Provide 'to_string' and 'to_code' functions to print enumerator // name(s) as human-readable strings or as code expressions -#line 2108 "reflect.h2" +#line 2117 "reflect.h2" { if (bitwise) { to_string_impl += ", separator: std::string_view ) -> std::string = { \n" @@ -5594,7 +5603,7 @@ std::string to_string_impl{" to_string_impl: (this, prefix: std::string_view" } } -#line 2147 "reflect.h2" +#line 2156 "reflect.h2" if (bitwise) { CPP2_UFCS(add_member)(t, " to_string: (this) -> std::string = to_string_impl( \"\", \", \" );"); CPP2_UFCS(add_member)(t, " to_code : (this) -> std::string = to_string_impl( \"" + cpp2::to_string(CPP2_UFCS(name)(t)) + "::\", \" | \" );"); @@ -5608,7 +5617,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ // Provide a 'from_string' function to parse strings into enumerators -#line 2158 "reflect.h2" +#line 2167 "reflect.h2" { std::string_view prefix {""}; std::string_view combine_op {"return"}; @@ -5630,7 +5639,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ { std::string_view else_{""}; -#line 2178 "reflect.h2" +#line 2187 "reflect.h2" for ( auto const& e : cpp2::move(enumerators) ) { from_string += " " + cpp2::to_string(else_) + "if \"" + cpp2::to_string(e.name) + "\" == x { " + cpp2::to_string(combine_op) + " " + cpp2::to_string(CPP2_UFCS(name)(t)) + "::" + cpp2::to_string(e.name) + "; }\n"; @@ -5638,7 +5647,7 @@ std::string_view else_{""}; } } -#line 2184 "reflect.h2" +#line 2193 "reflect.h2" if (bitwise) { from_string += " else { break outer; }\n" " }\n" @@ -5654,11 +5663,11 @@ std::string_view else_{""}; } } -#line 2198 "reflect.h2" +#line 2207 "reflect.h2" CPP2_UFCS(add_member)(t, " from_code: (s: std::string_view) -> " + cpp2::to_string(CPP2_UFCS(name)(t)) + " = { str: std::string = s; return from_string( cpp2::string_util::replace_all(str, \"" + cpp2::to_string(CPP2_UFCS(name)(t)) + "::\", \"\" ) ); }"); } -#line 2202 "reflect.h2" +#line 2211 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -5668,7 +5677,7 @@ std::string_view else_{""}; // // -- P0707R4, section 3 // -#line 2211 "reflect.h2" +#line 2220 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -5685,7 +5694,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 2228 "reflect.h2" +#line 2237 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -5696,7 +5705,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void // // -- P0707R4, section 3 // -#line 2238 "reflect.h2" +#line 2247 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -5718,7 +5727,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 2260 "reflect.h2" +#line 2269 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -5743,7 +5752,7 @@ auto flag_enum(meta::type_declaration& t) -> void // a type that contains exactly one of a fixed set of values at a time // -#line 2284 "reflect.h2" +#line 2293 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -5752,7 +5761,7 @@ auto value{0}; // 1. Gather: All the user-written members, and find/compute the max size -#line 2291 "reflect.h2" +#line 2300 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -5782,7 +5791,7 @@ auto value{0}; } while (false); ++value; } } -#line 2319 "reflect.h2" +#line 2328 "reflect.h2" std::string discriminator_type {}; if (cpp2::impl::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -5797,7 +5806,7 @@ auto value{0}; discriminator_type = "i64"; }}} -#line 2334 "reflect.h2" +#line 2343 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -5806,7 +5815,7 @@ std::string storage{" _storage: cpp2::aligned_storage t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 2441 "reflect.h2" +#line 2450 "reflect.h2" //----------------------------------------------------------------------- // // noisy - make each function print its name and signature, // so the programmer can see what's called // -#line 2446 "reflect.h2" +#line 2455 "reflect.h2" auto noisy(cpp2::impl::in t) -> void { for ( @@ -5943,12 +5952,12 @@ auto noisy(cpp2::impl::in t) -> void } } -#line 2463 "reflect.h2" +#line 2472 "reflect.h2" //----------------------------------------------------------------------- // // For reflection test cases // -#line 2467 "reflect.h2" +#line 2476 "reflect.h2" auto sample_print(cpp2::impl::in s, cpp2::impl::in indent) -> void { std::cout @@ -5957,12 +5966,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in << "\n"; } -#line 2477 "reflect.h2" +#line 2486 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in decl) -> void{ traverse(decl); } -#line 2481 "reflect.h2" +#line 2490 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in decl) -> void { if (CPP2_UFCS(is_function)(decl)) { @@ -5982,12 +5991,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // ... } -#line 2501 "reflect.h2" +#line 2510 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in f) -> void{ traverse(f); } -#line 2505 "reflect.h2" +#line 2514 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in f) -> void { auto parameters {CPP2_UFCS(get_parameters)(f)}; @@ -6008,12 +6017,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2526 "reflect.h2" +#line 2535 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in o) -> void{ traverse(o); } -#line 2530 "reflect.h2" +#line 2539 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in o) -> void { if (CPP2_UFCS(has_initializer)(o)) { @@ -6021,12 +6030,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2538 "reflect.h2" +#line 2547 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ traverse(t); } -#line 2542 "reflect.h2" +#line 2551 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in t) -> void { for ( auto const& m : CPP2_UFCS(get_members)(t) ) { @@ -6034,23 +6043,23 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2550 "reflect.h2" +#line 2559 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in t) -> void{ traverse(t); } -#line 2554 "reflect.h2" +#line 2563 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in t) -> void { pre_traverse(CPP2_UFCS(get_declaration)(t)); } -#line 2559 "reflect.h2" +#line 2568 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2563 "reflect.h2" +#line 2572 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6085,12 +6094,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // jump } -#line 2598 "reflect.h2" +#line 2607 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2602 "reflect.h2" +#line 2611 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6100,12 +6109,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2612 "reflect.h2" +#line 2621 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2616 "reflect.h2" +#line 2625 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(has_expression)(stmt)) { @@ -6113,12 +6122,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2624 "reflect.h2" +#line 2633 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2628 "reflect.h2" +#line 2637 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6137,12 +6146,12 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2647 "reflect.h2" +#line 2656 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in stmt) -> void{ traverse(stmt); } -#line 2651 "reflect.h2" +#line 2660 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in stmt) -> void { pre_traverse(CPP2_UFCS(get_expression)(stmt)); @@ -6153,14 +6162,14 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2662 "reflect.h2" +#line 2671 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in expr) -> void { // Nothing to select here. traverse(expr); } -#line 2668 "reflect.h2" +#line 2677 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in expr) -> void { // An expression has other shortcuts to query deeper properties, @@ -6174,7 +6183,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in pre_traverse(CPP2_UFCS(as_assignment_expression)(expr)); } -#line 2682 "reflect.h2" +#line 2691 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6192,7 +6201,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2699 "reflect.h2" +#line 2708 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6204,7 +6213,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2710 "reflect.h2" +#line 2719 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6222,7 +6231,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2727 "reflect.h2" +#line 2736 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6234,7 +6243,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2739 "reflect.h2" +#line 2748 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6252,7 +6261,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2756 "reflect.h2" +#line 2765 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6264,7 +6273,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2767 "reflect.h2" +#line 2776 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6282,7 +6291,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2784 "reflect.h2" +#line 2793 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6294,7 +6303,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2795 "reflect.h2" +#line 2804 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6312,7 +6321,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2812 "reflect.h2" +#line 2821 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6324,7 +6333,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2824 "reflect.h2" +#line 2833 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6342,7 +6351,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2841 "reflect.h2" +#line 2850 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6354,7 +6363,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2853 "reflect.h2" +#line 2862 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6372,7 +6381,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2870 "reflect.h2" +#line 2879 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6384,7 +6393,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2881 "reflect.h2" +#line 2890 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6402,7 +6411,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2898 "reflect.h2" +#line 2907 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6414,7 +6423,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2909 "reflect.h2" +#line 2918 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6432,7 +6441,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2926 "reflect.h2" +#line 2935 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6444,7 +6453,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2937 "reflect.h2" +#line 2946 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6462,7 +6471,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2954 "reflect.h2" +#line 2963 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6474,7 +6483,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2965 "reflect.h2" +#line 2974 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6492,7 +6501,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2982 "reflect.h2" +#line 2991 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6504,7 +6513,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 2994 "reflect.h2" +#line 3003 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6522,7 +6531,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3011 "reflect.h2" +#line 3020 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in binexpr) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6534,7 +6543,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3022 "reflect.h2" +#line 3031 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6551,7 +6560,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3038 "reflect.h2" +#line 3047 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in isas) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -6563,7 +6572,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3049 "reflect.h2" +#line 3058 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in exprs) -> void { for ( auto const& expr : CPP2_UFCS(get_expressions)(exprs) ) { @@ -6571,7 +6580,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3056 "reflect.h2" +#line 3065 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -6588,13 +6597,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3072 "reflect.h2" +#line 3081 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in prefix) -> void { pre_traverse(CPP2_UFCS(get_postfix_expression)(prefix)); } -#line 3077 "reflect.h2" +#line 3086 "reflect.h2" auto simple_traverser::pre_traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6611,7 +6620,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3093 "reflect.h2" +#line 3102 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -6631,13 +6640,13 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3112 "reflect.h2" +#line 3121 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in uid) -> void { static_cast(uid); } -#line 3118 "reflect.h2" +#line 3127 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in qid) -> void { for ( @@ -6647,7 +6656,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in } } -#line 3128 "reflect.h2" +#line 3137 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in tid) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -6664,7 +6673,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 3145 "reflect.h2" +#line 3154 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -6684,7 +6693,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}}} } -#line 3165 "reflect.h2" +#line 3174 "reflect.h2" auto simple_traverser::traverse(cpp2::impl::in idexpr) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -6701,7 +6710,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in }}} } -#line 3183 "reflect.h2" +#line 3192 "reflect.h2" //----------------------------------------------------------------------- // // sample_traverser serves two purposes: @@ -6712,7 +6721,7 @@ auto sample_print(cpp2::impl::in s, cpp2::impl::in // for reflecting on function bodies (statements, expressions) // -#line 3193 "reflect.h2" +#line 3202 "reflect.h2" auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in indent) -> void { sample_print("Declaration: " + cpp2::to_string(CPP2_UFCS(name)(decl)) + "", indent); @@ -6734,7 +6743,7 @@ auto sample_traverser(cpp2::impl::in decl, cpp2::impl::in f, cpp2::impl::in indent) -> void { sample_print("Function: " + cpp2::to_string(CPP2_UFCS(name)(f)) + "", indent + 1); @@ -6764,7 +6773,7 @@ auto sample_traverser(cpp2::impl::in f, cpp2::impl:: } } -#line 3245 "reflect.h2" +#line 3254 "reflect.h2" auto sample_traverser(cpp2::impl::in o, cpp2::impl::in indent) -> void { sample_print("Object: name " + cpp2::to_string(CPP2_UFCS(name)(o)) + ", type " + cpp2::to_string(CPP2_UFCS(type)(o)) + "", indent); @@ -6774,7 +6783,7 @@ auto sample_traverser(cpp2::impl::in o, cpp2::impl::in } } -#line 3255 "reflect.h2" +#line 3264 "reflect.h2" auto sample_traverser(cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("Type: " + cpp2::to_string(CPP2_UFCS(name)(t)) + "", indent); @@ -6793,7 +6802,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl::in t, cpp2::impl::in indent) -> void { sample_print("parameter:", indent); @@ -6812,7 +6821,7 @@ auto sample_traverser(cpp2::impl::in t, cpp2::impl: sample_traverser(CPP2_UFCS(get_declaration)(t), indent + 2); } -#line 3293 "reflect.h2" +#line 3302 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_expression_statement)(stmt)) { @@ -6859,7 +6868,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in stmt, cpp2::impl::in indent) -> void { auto stmts {CPP2_UFCS(get_statements)(stmt)}; @@ -6876,7 +6885,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl: } } -#line 3357 "reflect.h2" +#line 3366 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { sample_print("return statement", indent); @@ -6886,7 +6895,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::i } } -#line 3367 "reflect.h2" +#line 3376 "reflect.h2" auto sample_traverser(cpp2::impl::in stmt, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_do)(stmt) || CPP2_UFCS(is_while)(stmt)) { @@ -6918,7 +6927,7 @@ auto sample_traverser(cpp2::impl::in stmt, cpp2::impl } } -#line 3399 "reflect.h2" +#line 3408 "reflect.h2" auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in indent) -> void { // An expression has other shortcuts to query deeper properties, @@ -6932,7 +6941,7 @@ auto sample_traverser(cpp2::impl::in expr, cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6950,7 +6959,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3429 "reflect.h2" +#line 3438 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6962,11 +6971,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3439 "reflect.h2" +#line 3448 "reflect.h2" } } -#line 3443 "reflect.h2" +#line 3452 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -6984,7 +6993,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3459 "reflect.h2" +#line 3468 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -6996,11 +7005,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3469 "reflect.h2" +#line 3478 "reflect.h2" } } -#line 3473 "reflect.h2" +#line 3482 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7018,7 +7027,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2 { auto first{true}; -#line 3489 "reflect.h2" +#line 3498 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7030,11 +7039,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3499 "reflect.h2" +#line 3508 "reflect.h2" } } -#line 3503 "reflect.h2" +#line 3512 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7052,7 +7061,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::imp { auto first{true}; -#line 3519 "reflect.h2" +#line 3528 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7064,11 +7073,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3529 "reflect.h2" +#line 3538 "reflect.h2" } } -#line 3533 "reflect.h2" +#line 3542 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7086,7 +7095,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3549 "reflect.h2" +#line 3558 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7098,11 +7107,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3559 "reflect.h2" +#line 3568 "reflect.h2" } } -#line 3563 "reflect.h2" +#line 3572 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7120,7 +7129,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3579 "reflect.h2" +#line 3588 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7132,11 +7141,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3589 "reflect.h2" +#line 3598 "reflect.h2" } } -#line 3593 "reflect.h2" +#line 3602 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7154,7 +7163,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3609 "reflect.h2" +#line 3618 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7166,11 +7175,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3619 "reflect.h2" +#line 3628 "reflect.h2" } } -#line 3623 "reflect.h2" +#line 3632 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7188,7 +7197,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2: { auto first{true}; -#line 3639 "reflect.h2" +#line 3648 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7200,11 +7209,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3649 "reflect.h2" +#line 3658 "reflect.h2" } } -#line 3653 "reflect.h2" +#line 3662 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7222,7 +7231,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::im { auto first{true}; -#line 3669 "reflect.h2" +#line 3678 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7234,11 +7243,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3679 "reflect.h2" +#line 3688 "reflect.h2" } } -#line 3683 "reflect.h2" +#line 3692 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7256,7 +7265,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl { auto first{true}; -#line 3699 "reflect.h2" +#line 3708 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7268,11 +7277,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3709 "reflect.h2" +#line 3718 "reflect.h2" } } -#line 3713 "reflect.h2" +#line 3722 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7290,7 +7299,7 @@ auto sample_traverser(cpp2::impl::in binexpr, cpp2::i { auto first{true}; -#line 3729 "reflect.h2" +#line 3738 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7302,11 +7311,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3739 "reflect.h2" +#line 3748 "reflect.h2" } } -#line 3743 "reflect.h2" +#line 3752 "reflect.h2" auto sample_traverser(cpp2::impl::in binexpr, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -7324,7 +7333,7 @@ auto sample_traverser(cpp2::impl::in binexpr, c { auto first{true}; -#line 3759 "reflect.h2" +#line 3768 "reflect.h2" for ( auto const& term : cpp2::move(terms) ) { @@ -7336,11 +7345,11 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_term)(term), indent + 2); } } -#line 3769 "reflect.h2" +#line 3778 "reflect.h2" } } -#line 3773 "reflect.h2" +#line 3782 "reflect.h2" auto sample_traverser(cpp2::impl::in isas, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(isas)}; @@ -7366,7 +7375,7 @@ auto sample_traverser(cpp2::impl::in isas, cpp2::impl::i } } -#line 3799 "reflect.h2" +#line 3808 "reflect.h2" auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_empty)(exprs)) { @@ -7381,7 +7390,7 @@ auto sample_traverser(cpp2::impl::in exprs, cpp2::impl::i } } -#line 3814 "reflect.h2" +#line 3823 "reflect.h2" auto sample_traverser(cpp2::impl::in prefix, cpp2::impl::in indent) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -7405,7 +7414,7 @@ auto sample_traverser(cpp2::impl::in prefix, cpp2::impl } } -#line 3838 "reflect.h2" +#line 3847 "reflect.h2" auto sample_traverser(cpp2::impl::in postfix, cpp2::impl::in indent) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7438,7 +7447,7 @@ auto sample_traverser(cpp2::impl::in postfix, cpp2::im } } -#line 3871 "reflect.h2" +#line 3880 "reflect.h2" auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(uid)) { @@ -7449,13 +7458,13 @@ auto sample_traverser(cpp2::impl::in uid, cpp2::impl::in qid, cpp2::impl::in indent) -> void { { auto first{true}; -#line 3885 "reflect.h2" +#line 3894 "reflect.h2" for ( auto const& term : CPP2_UFCS(get_terms)(qid) ) { @@ -7467,10 +7476,10 @@ auto first{true}; sample_traverser(CPP2_UFCS(get_unqualified)(term), indent + 2); } } -#line 3895 "reflect.h2" +#line 3904 "reflect.h2" } -#line 3898 "reflect.h2" +#line 3907 "reflect.h2" auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_postfix_expression)(tid)) { @@ -7487,7 +7496,7 @@ auto sample_traverser(cpp2::impl::in tid, cpp2::impl::in primary, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -7507,7 +7516,7 @@ auto sample_traverser(cpp2::impl::in primary, cpp2::im }}}} } -#line 3935 "reflect.h2" +#line 3944 "reflect.h2" auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in indent) -> void { if (CPP2_UFCS(is_identifier)(idexpr)) { @@ -7524,13 +7533,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }}} } -#line 3952 "reflect.h2" +#line 3961 "reflect.h2" //----------------------------------------------------------------------- // // autodiff - stub // -#line 3966 "reflect.h2" +#line 3975 "reflect.h2" autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_, cpp2::impl::in code_higher_order_) : name{ name_ } , n_args{ n_args_ } @@ -7539,13 +7548,13 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , code{ code_ } , code_higher_order{ code_higher_order_ }{ -#line 3974 "reflect.h2" +#line 3983 "reflect.h2" if (CPP2_UFCS(empty)(code_higher_order)) { code_higher_order = code; } } -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) : name{ that.name } , n_args{ that.n_args } @@ -7553,7 +7562,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , is_member{ that.is_member } , code{ that.code } , code_higher_order{ that.code_higher_order }{} -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { name = that.name; n_args = that.n_args; @@ -7562,7 +7571,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in code = that.code; code_higher_order = that.code_higher_order; return *this; } -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept : name{ std::move(that).name } , n_args{ std::move(that).n_args } @@ -7570,7 +7579,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in , is_member{ std::move(that).is_member } , code{ std::move(that).code } , code_higher_order{ std::move(that).code_higher_order }{} -#line 3979 "reflect.h2" +#line 3988 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { name = std::move(that).name; n_args = std::move(that).n_args; @@ -7580,26 +7589,26 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in code_higher_order = std::move(that).code_higher_order; return *this; }// Default copy. -#line 3981 "reflect.h2" +#line 3990 "reflect.h2" [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; } -#line 3987 "reflect.h2" +#line 3996 "reflect.h2" // namespace + type name -#line 3993 "reflect.h2" +#line 4002 "reflect.h2" autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) : full_name{ full_name_ } , decl{ decl_ }{ -#line 3996 "reflect.h2" +#line 4005 "reflect.h2" } -#line 3998 "reflect.h2" +#line 4007 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 3999 "reflect.h2" +#line 4008 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -7620,7 +7629,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , diff_request{ std::move(that).diff_request } , diff_done{ std::move(that).diff_done }{} -#line 4012 "reflect.h2" +#line 4021 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7633,19 +7642,19 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar /* has_return = */ /* is_member = */ -#line 4029 "reflect.h2" +#line 4038 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4036 "reflect.h2" +#line 4045 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4042 "reflect.h2" +#line 4051 "reflect.h2" /* has_return = */ /* is_member = */ -#line 4050 "reflect.h2" +#line 4059 "reflect.h2" // Members depending on order -#line 4056 "reflect.h2" +#line 4065 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -7663,7 +7672,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4073 "reflect.h2" +#line 4082 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7675,17 +7684,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4084 "reflect.h2" +#line 4093 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4086 "reflect.h2" +#line 4095 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4092 "reflect.h2" +#line 4101 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ if (order == 1) { @@ -7695,10 +7704,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(type, "double", ad_type); } -#line 4101 "reflect.h2" +#line 4110 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4102 "reflect.h2" +#line 4111 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7721,10 +7730,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4124 "reflect.h2" +#line 4133 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4125 "reflect.h2" +#line 4134 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7734,11 +7743,11 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4134 "reflect.h2" +#line 4143 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code; -#line 4135 "reflect.h2" +#line 4144 "reflect.h2" autodiff_special_func lookup {func_name, n_args, has_return, is_member}; m.construct(false); @@ -7757,7 +7766,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code.value()) }; } -#line 4153 "reflect.h2" +#line 4162 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -7766,7 +7775,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4161 "reflect.h2" +#line 4170 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -7787,7 +7796,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4181 "reflect.h2" +#line 4190 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -7798,16 +7807,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4191 "reflect.h2" +#line 4200 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4195 "reflect.h2" +#line 4204 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4198 "reflect.h2" +#line 4207 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -7821,52 +7830,50 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4211 "reflect.h2" +#line 4220 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } auto top {&CPP2_UFCS(back)(declaration_stack)}; + autodiff_declaration_handler ad {&(*this), (*cpp2::impl::assert_not_null(top)).decl}; for ( auto const& cur : (*cpp2::impl::assert_not_null(top)).diff_request ) { if (!(is_in_list(cur, (*cpp2::impl::assert_not_null(top)).diff_done))) { - // TODO: Implement declaration diff handling - // ad: autodiff_declaration_handler = (this); - // ad.pre_traverse(cur); - CPP2_UFCS(error)((*cpp2::impl::assert_not_null(top)).decl, "AD: diff for `" + cpp2::to_string(CPP2_UFCS(name)(cur)) + "` in `" + cpp2::to_string(CPP2_UFCS(name)((*cpp2::impl::assert_not_null(top)).decl)) + "` requested."); + CPP2_UFCS(pre_traverse)(ad, cur); } } CPP2_UFCS(pop_back)(declaration_stack); } -#line 4228 "reflect.h2" +#line 4235 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4240 "reflect.h2" +#line 4247 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4242 "reflect.h2" +#line 4249 "reflect.h2" } -#line 4240 "reflect.h2" +#line 4247 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4242 "reflect.h2" +#line 4249 "reflect.h2" } -#line 4244 "reflect.h2" +#line 4251 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4259 "reflect.h2" +#line 4266 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } @@ -7874,13 +7881,13 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , declare_p{ declare_p_ } , declare_d{ declare_d_ }{ -#line 4265 "reflect.h2" +#line 4272 "reflect.h2" if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { declare_d = declare_p; } } -#line 4270 "reflect.h2" +#line 4277 "reflect.h2" auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; if (lhs == "_") { @@ -7900,7 +7907,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4289 "reflect.h2" +#line 4296 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7910,7 +7917,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return args; } -#line 4298 "reflect.h2" +#line 4305 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7949,7 +7956,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }} } -#line 4336 "reflect.h2" +#line 4343 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7957,7 +7964,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4342 "reflect.h2" +#line 4349 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7971,7 +7978,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4354 "reflect.h2" +#line 4361 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7994,7 +8001,7 @@ auto i{0}; { auto i{0}; -#line 4375 "reflect.h2" +#line 4382 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8019,7 +8026,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4398 "reflect.h2" +#line 4405 "reflect.h2" auto r_arg {lhs}; if (!(has_return)) { r_arg = ""; @@ -8080,7 +8087,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4458 "reflect.h2" +#line 4465 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; @@ -8105,75 +8112,75 @@ auto i{0}; { auto i{1}; -#line 4481 "reflect.h2" +#line 4488 "reflect.h2" for ( auto const& arg : args ) { code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4486 "reflect.h2" +#line 4493 "reflect.h2" diff += cpp2::move(code); return true; } -#line 4491 "reflect.h2" +#line 4498 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4495 "reflect.h2" +#line 4502 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4499 "reflect.h2" +#line 4506 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4503 "reflect.h2" +#line 4510 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4507 "reflect.h2" +#line 4514 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4511 "reflect.h2" +#line 4518 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4515 "reflect.h2" +#line 4522 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4519 "reflect.h2" +#line 4526 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4523 "reflect.h2" +#line 4530 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4527 "reflect.h2" +#line 4534 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4531 "reflect.h2" +#line 4538 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4535 "reflect.h2" +#line 4542 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8198,7 +8205,7 @@ auto i{1}; gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); } -#line 4559 "reflect.h2" +#line 4566 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8237,7 +8244,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4598 "reflect.h2" +#line 4605 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { // Last item gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); @@ -8256,18 +8263,18 @@ auto i{1}; } } -#line 4616 "reflect.h2" +#line 4623 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4620 "reflect.h2" +#line 4627 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4625 "reflect.h2" +#line 4632 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8276,7 +8283,7 @@ auto i{1}; { auto i{0}; -#line 4632 "reflect.h2" +#line 4639 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8290,7 +8297,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4644 "reflect.h2" +#line 4651 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8299,7 +8306,7 @@ auto i{0}; handle_function_call(postfix, true); } -#line 4652 "reflect.h2" +#line 4659 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8332,26 +8339,26 @@ auto i{0}; }}}} } -#line 4693 "reflect.h2" +#line 4700 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4696 "reflect.h2" +#line 4703 "reflect.h2" } -#line 4698 "reflect.h2" +#line 4705 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4703 "reflect.h2" +#line 4710 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4708 "reflect.h2" +#line 4715 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8369,22 +8376,22 @@ auto i{0}; } } -#line 4726 "reflect.h2" +#line 4733 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4731 "reflect.h2" +#line 4738 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4736 "reflect.h2" +#line 4743 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4741 "reflect.h2" +#line 4748 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8392,7 +8399,7 @@ auto i{0}; diff += "}\n"; } -#line 4749 "reflect.h2" +#line 4756 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8408,7 +8415,7 @@ auto i{0}; } } -#line 4765 "reflect.h2" +#line 4772 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8455,7 +8462,7 @@ auto i{0}; }} } -#line 4812 "reflect.h2" +#line 4819 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8467,7 +8474,7 @@ auto i{0}; } } -#line 4823 "reflect.h2" +#line 4830 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8496,79 +8503,79 @@ auto i{0}; } } -#line 4851 "reflect.h2" +#line 4858 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4856 "reflect.h2" +#line 4863 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4860 "reflect.h2" +#line 4867 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4864 "reflect.h2" +#line 4871 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4868 "reflect.h2" +#line 4875 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4872 "reflect.h2" +#line 4879 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4876 "reflect.h2" +#line 4883 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4880 "reflect.h2" +#line 4887 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4884 "reflect.h2" +#line 4891 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4888 "reflect.h2" +#line 4895 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4892 "reflect.h2" +#line 4899 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4896 "reflect.h2" +#line 4903 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4900 "reflect.h2" +#line 4907 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4904 "reflect.h2" +#line 4911 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4909 "reflect.h2" +#line 4916 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8577,7 +8584,7 @@ auto i{0}; { auto i{0}; -#line 4916 "reflect.h2" +#line 4923 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8591,7 +8598,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4928 "reflect.h2" +#line 4935 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8602,27 +8609,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4938 "reflect.h2" +#line 4945 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4952 "reflect.h2" +#line 4959 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4955 "reflect.h2" +#line 4962 "reflect.h2" } -#line 4957 "reflect.h2" +#line 4964 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4962 "reflect.h2" +#line 4969 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8666,10 +8673,10 @@ auto i{0}; return ; } -#line 5006 "reflect.h2" +#line 5013 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5009 "reflect.h2" +#line 5016 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8686,12 +8693,12 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5026 "reflect.h2" +#line 5033 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ CPP2_UFCS(error)(o, "AD: Do not know how to handle object_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(o)) + ""); } -#line 5031 "reflect.h2" +#line 5038 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -8706,17 +8713,17 @@ auto i{0}; CPP2_UFCS(pop_stack)((*cpp2::impl::assert_not_null(ctx))); } -#line 5046 "reflect.h2" +#line 5053 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5051 "reflect.h2" +#line 5058 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5057 "reflect.h2" +#line 5064 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8752,7 +8759,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5093 "reflect.h2" +#line 5100 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8881,7 +8888,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5131 "reflect.h2" +#line 5138 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8897,11 +8904,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5147 "reflect.h2" +#line 5154 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5151 "reflect.h2" +#line 5158 "reflect.h2" // mod: i // mod: m // mod: s @@ -8909,116 +8916,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5160 "reflect.h2" +#line 5167 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5169 "reflect.h2" +#line 5176 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5171 "reflect.h2" +#line 5178 "reflect.h2" } -#line 5173 "reflect.h2" +#line 5180 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5175 "reflect.h2" +#line 5182 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5181 "reflect.h2" +#line 5188 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5182 "reflect.h2" +#line 5189 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5183 "reflect.h2" +#line 5190 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5198 "reflect.h2" +#line 5205 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5201 "reflect.h2" +#line 5208 "reflect.h2" } -#line 5203 "reflect.h2" +#line 5210 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5207 "reflect.h2" +#line 5214 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5219 "reflect.h2" +#line 5226 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5222 "reflect.h2" +#line 5229 "reflect.h2" } -#line 5224 "reflect.h2" +#line 5231 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5228 "reflect.h2" +#line 5235 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5238 "reflect.h2" +#line 5245 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5240 "reflect.h2" +#line 5247 "reflect.h2" } -#line 5242 "reflect.h2" +#line 5249 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5246 "reflect.h2" +#line 5253 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5258 "reflect.h2" +#line 5265 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5261 "reflect.h2" +#line 5268 "reflect.h2" } -#line 5263 "reflect.h2" +#line 5270 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5269 "reflect.h2" +#line 5276 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5275 "reflect.h2" +#line 5282 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9027,7 +9034,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5283 "reflect.h2" +#line 5290 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9043,7 +9050,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5311 "reflect.h2" +#line 5318 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9051,14 +9058,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5319 "reflect.h2" +#line 5326 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5326 "reflect.h2" +#line 5333 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9070,15 +9077,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5338 "reflect.h2" +#line 5345 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5343 "reflect.h2" +#line 5350 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5347 "reflect.h2" +#line 5354 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9099,7 +9106,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5373 "reflect.h2" +#line 5380 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9108,20 +9115,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5382 "reflect.h2" +#line 5389 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5388 "reflect.h2" +#line 5395 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5395 "reflect.h2" +#line 5402 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9136,16 +9143,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5425 "reflect.h2" +#line 5432 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5429 "reflect.h2" +#line 5436 "reflect.h2" } -#line 5435 "reflect.h2" +#line 5442 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9155,7 +9162,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5445 "reflect.h2" +#line 5452 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9163,17 +9170,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5452 "reflect.h2" +#line 5459 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5456 "reflect.h2" +#line 5463 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5463 "reflect.h2" +#line 5470 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9183,7 +9190,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5472 "reflect.h2" +#line 5479 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9191,24 +9198,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5479 "reflect.h2" +#line 5486 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5487 "reflect.h2" +#line 5494 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5491 "reflect.h2" +#line 5498 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5495 "reflect.h2" +#line 5502 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9220,22 +9227,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5506 "reflect.h2" +#line 5513 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5512 "reflect.h2" +#line 5519 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5516 "reflect.h2" +#line 5523 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5520 "reflect.h2" +#line 5527 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9243,7 +9250,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5527 "reflect.h2" +#line 5534 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9255,10 +9262,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5540 "reflect.h2" +#line 5547 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5543 "reflect.h2" +#line 5550 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9298,7 +9305,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5583 "reflect.h2" +#line 5590 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9310,14 +9317,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5594 "reflect.h2" +#line 5601 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5595 "reflect.h2" +#line 5602 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5596 "reflect.h2" +#line 5603 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5598 "reflect.h2" +#line 5605 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9327,10 +9334,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5607 "reflect.h2" +#line 5614 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5609 "reflect.h2" +#line 5616 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9352,14 +9359,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5630 "reflect.h2" +#line 5637 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5631 "reflect.h2" +#line 5638 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5632 "reflect.h2" +#line 5639 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5634 "reflect.h2" +#line 5641 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9373,7 +9380,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5647 "reflect.h2" +#line 5654 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9395,7 +9402,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5668 "reflect.h2" +#line 5675 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9406,12 +9413,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5678 "reflect.h2" +#line 5685 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5679 "reflect.h2" +#line 5686 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5684 "reflect.h2" +#line 5691 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9466,7 +9473,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5738 "reflect.h2" +#line 5745 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9506,7 +9513,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5777 "reflect.h2" +#line 5784 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9522,21 +9529,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5794 "reflect.h2" +#line 5801 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5795 "reflect.h2" +#line 5802 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5796 "reflect.h2" +#line 5803 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5798 "reflect.h2" +#line 5805 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5813 "reflect.h2" +#line 5820 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9544,7 +9551,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5820 "reflect.h2" +#line 5827 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9554,22 +9561,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5838 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5843 "reflect.h2" +#line 5850 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5849 "reflect.h2" +#line 5856 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5855 "reflect.h2" +#line 5862 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9578,7 +9585,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5863 "reflect.h2" +#line 5870 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9590,7 +9597,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5874 "reflect.h2" +#line 5881 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9598,7 +9605,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5881 "reflect.h2" +#line 5888 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9619,7 +9626,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5902 "reflect.h2" +#line 5909 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9629,7 +9636,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5912 "reflect.h2" +#line 5919 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9652,33 +9659,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5936 "reflect.h2" +#line 5943 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5942 "reflect.h2" +#line 5949 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5946 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5952 "reflect.h2" +#line 5959 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5960 "reflect.h2" +#line 5967 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9687,7 +9694,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5968 "reflect.h2" +#line 5975 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9696,22 +9703,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5978 "reflect.h2" +#line 5985 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5982 "reflect.h2" +#line 5989 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5986 "reflect.h2" +#line 5993 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5990 "reflect.h2" +#line 5997 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9735,18 +9742,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6015 "reflect.h2" +#line 6022 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6030 "reflect.h2" +#line 6037 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6032 "reflect.h2" +#line 6039 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9757,15 +9764,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6047 "reflect.h2" +#line 6054 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6050 "reflect.h2" +#line 6057 "reflect.h2" } -#line 6052 "reflect.h2" +#line 6059 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9783,7 +9790,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6069 "reflect.h2" +#line 6076 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9791,7 +9798,7 @@ generation_function_context::generation_function_context(){} } } -#line 6076 "reflect.h2" +#line 6083 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9805,7 +9812,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6089 "reflect.h2" +#line 6096 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9821,14 +9828,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6110 "reflect.h2" +#line 6117 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6112 "reflect.h2" +#line 6119 "reflect.h2" } -#line 6114 "reflect.h2" +#line 6121 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9837,11 +9844,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6129 "reflect.h2" +#line 6136 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6131 "reflect.h2" +#line 6138 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9849,7 +9856,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6138 "reflect.h2" +#line 6145 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9858,37 +9865,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6146 "reflect.h2" +#line 6153 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6160 "reflect.h2" +#line 6167 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6164 "reflect.h2" +#line 6171 "reflect.h2" } -#line 6166 "reflect.h2" +#line 6173 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6170 "reflect.h2" +#line 6177 "reflect.h2" } -#line 6172 "reflect.h2" +#line 6179 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6176 "reflect.h2" +#line 6183 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9897,14 +9904,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6182 "reflect.h2" +#line 6189 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6187 "reflect.h2" +#line 6194 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9917,7 +9924,7 @@ size_t i{0}; } } -#line 6199 "reflect.h2" +#line 6206 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9939,7 +9946,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6220 "reflect.h2" +#line 6227 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9958,7 +9965,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6238 "reflect.h2" +#line 6245 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9974,14 +9981,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6253 "reflect.h2" +#line 6260 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6259 "reflect.h2" +#line 6266 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9989,19 +9996,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6276 "reflect.h2" +#line 6283 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6277 "reflect.h2" +#line 6284 "reflect.h2" { -#line 6282 "reflect.h2" +#line 6289 "reflect.h2" } -#line 6285 "reflect.h2" +#line 6292 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10127,7 +10134,7 @@ size_t i{0}; ); } -#line 6410 "reflect.h2" +#line 6417 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10137,13 +10144,13 @@ size_t i{0}; ); } -#line 6419 "reflect.h2" +#line 6426 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6424 "reflect.h2" +#line 6431 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10154,12 +10161,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6436 "reflect.h2" +#line 6443 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6441 "reflect.h2" +#line 6448 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10193,7 +10200,7 @@ size_t i{0}; } -#line 6477 "reflect.h2" +#line 6484 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10202,19 +10209,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6500 "reflect.h2" +#line 6507 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6501 "reflect.h2" +#line 6508 "reflect.h2" { -#line 6506 "reflect.h2" +#line 6513 "reflect.h2" } -#line 6508 "reflect.h2" +#line 6515 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10316,19 +10323,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6609 "reflect.h2" +#line 6616 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6613 "reflect.h2" +#line 6620 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6637 "reflect.h2" +#line 6644 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10347,7 +10354,7 @@ size_t i{0}; return r; } -#line 6655 "reflect.h2" +#line 6662 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10362,7 +10369,7 @@ size_t i{0}; return r; } -#line 6669 "reflect.h2" +#line 6676 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10522,7 +10529,7 @@ size_t i{0}; } } -#line 6828 "reflect.h2" +#line 6835 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10531,7 +10538,7 @@ size_t i{0}; return r; } -#line 6836 "reflect.h2" +#line 6843 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10550,7 +10557,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6854 "reflect.h2" +#line 6861 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10582,7 +10589,7 @@ size_t i{0}; } } -#line 6885 "reflect.h2" +#line 6892 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10593,7 +10600,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6897 "reflect.h2" +#line 6904 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10632,7 +10639,7 @@ size_t i{0}; return r; } -#line 6938 "reflect.h2" +#line 6945 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10650,7 +10657,7 @@ size_t i{0}; }} } -#line 6958 "reflect.h2" +#line 6965 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10664,16 +10671,16 @@ size_t i{0}; } } -#line 6984 "reflect.h2" +#line 6991 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6987 "reflect.h2" +#line 6994 "reflect.h2" } -#line 6989 "reflect.h2" +#line 6996 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10685,7 +10692,7 @@ size_t i{0}; } } -#line 7000 "reflect.h2" +#line 7007 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10693,14 +10700,14 @@ size_t i{0}; return r; } -#line 7007 "reflect.h2" +#line 7014 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7015 "reflect.h2" +#line 7022 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10726,7 +10733,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7043 "reflect.h2" +#line 7050 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10752,11 +10759,11 @@ size_t i{0}; return r; } -#line 7080 "reflect.h2" +#line 7087 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7082 "reflect.h2" +#line 7089 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10830,7 +10837,7 @@ size_t i{0}; return nullptr; } -#line 7155 "reflect.h2" +#line 7162 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10843,7 +10850,7 @@ size_t i{0}; }} } -#line 7167 "reflect.h2" +#line 7174 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10857,7 +10864,7 @@ size_t i{0}; }} } -#line 7180 "reflect.h2" +#line 7187 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10877,7 +10884,7 @@ size_t i{0}; return r; } -#line 7199 "reflect.h2" +#line 7206 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10888,7 +10895,7 @@ size_t i{0}; return r; } -#line 7209 "reflect.h2" +#line 7216 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10900,14 +10907,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7220 "reflect.h2" +#line 7227 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7232 "reflect.h2" +#line 7239 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10931,7 +10938,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7256 "reflect.h2" +#line 7263 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10941,7 +10948,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7268 "reflect.h2" +#line 7275 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10957,7 +10964,7 @@ size_t i{0}; } } -#line 7288 "reflect.h2" +#line 7295 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10975,15 +10982,15 @@ size_t i{0}; }} } -#line 7324 "reflect.h2" +#line 7331 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7327 "reflect.h2" +#line 7334 "reflect.h2" } -#line 7329 "reflect.h2" +#line 7336 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11019,7 +11026,7 @@ size_t i{0}; return source; } -#line 7364 "reflect.h2" +#line 7371 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11035,7 +11042,7 @@ size_t i{0}; } } -#line 7380 "reflect.h2" +#line 7387 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11044,7 +11051,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11099,7 +11106,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7449 "reflect.h2" +#line 7456 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11221,7 +11228,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7571 "reflect.h2" +#line 7578 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 63f899374..242bf2a1d 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -552,8 +552,17 @@ type_or_namespace_declaration: @copy_constructible type = if !decl*.is_declaration() { error("cannot add a member that is not a declaration"); } - require( n*.add_type_member(move decl), + + if is_namespace() { + require( n*.add_namespace_member(move decl), + std::string("unexpected error while attempting to add member:\n") + source ); + + } + else { + assert(is_type()); + require( n*.add_type_member(move decl), std::string("unexpected error while attempting to add member:\n") + source ); + } } } @@ -4212,13 +4221,11 @@ autodiff_context: type = { assert(!declaration_stack.empty()); top := declaration_stack.back()&; + ad: autodiff_declaration_handler = (this&, top*.decl); for top*.diff_request do (cur) { if !is_in_list(cur, top*.diff_done) { - // TODO: Implement declaration diff handling - // ad: autodiff_declaration_handler = (this); - // ad.pre_traverse(cur); - top*.decl.error("AD: diff for `(cur.name())$` in `(top*.decl.name())$` requested."); + ad.pre_traverse(cur); } } From 6d2659c71802d92fc41ad06f193a5945d9ea6bf2 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 08:07:16 +0200 Subject: [PATCH 31/54] Basic differentation for type and namespace value declarations. --- source/reflect.h2 | 79 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/source/reflect.h2 b/source/reflect.h2 index df3a8a166..6aa3b7304 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4094,6 +4094,7 @@ autodiff_context: type = { // TODO: Have the proper type declaration here. get_ad_type: (inout this, type: std::string) -> std::string = { + // TODO: Lookup if type is a known type and if it has AD values. if order == 1 { return type; // Same type for now for order 1 } @@ -4257,6 +4258,8 @@ autodiff_expression_handler: type = { public declare_p: std::string; public declare_d: std::string; + public primal_gen: bool = true; + operator=: (out this, ctx_: *autodiff_context, lhs_: std::string, declare_p_: std::string = "", declare_d_: std::string = "") = { autodiff_handler_base = (ctx_); lhs = lhs_; @@ -4278,11 +4281,11 @@ autodiff_expression_handler: type = { fwd_str := "(lhs_d)$ (declare_d)$ = (fwd)$;\n"; primal_str := "(lhs)$ (declare_p)$ = (prim)$;\n"; - if primal_first { + if primal_gen && primal_first { diff += primal_str; } diff += fwd_str; - if !primal_first { + if primal_gen && !primal_first { diff += primal_str; } } @@ -4606,7 +4609,9 @@ autodiff_expression_handler: type = { t_d := t + ctx*.suffix; // TODO: Get type of expression, in order to define the type of t. diff += "(t_d)$ := (fwd)$;"; - diff += "(t)$ := (primal)$;"; + if primal_gen { + diff += "(t)$ := (primal)$;"; + } arg_a = t; arg_a_d = t_d; @@ -4627,7 +4632,7 @@ autodiff_expression_handler: type = { { terms := postfix.get_terms(); - is_func := true; + is_func := false; (copy i := 0) for terms next i += 1 do (term) { @@ -4635,19 +4640,31 @@ autodiff_expression_handler: type = { continue; } if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + is_func = true; continue; } - - is_func = false; + else { + postfix.error("AD: Unknown operator for postfix expression. op: (term.get_op())$ expr: (postfix)$"); + } } - // Check for function call, everything else is not handled. - if !(is_func) { - postfix.error( "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: (postfix.to_string())$" ); - return; + if is_func { + handle_function_call(postfix, true); } + else { + // Member access + + primary : = postfix.get_primary_expression(); + obj_name : std::string = primary.to_string(); + obj_name_d : std::string = obj_name + ctx*.suffix; + obj_access : std::string = ""; + + for terms do (term) { + obj_access += term.get_op() + term.get_id_expression().to_string(); + } - handle_function_call(postfix, true); + gen_lhs_assignment("(obj_name)$(obj_access)$", "(obj_name_d)$(obj_access)$"); + } } traverse: (override inout this, primary: meta::primary_expression) = @@ -4911,7 +4928,7 @@ autodiff_stmt_handler: type = { { terms := postfix.get_terms(); - is_func := true; + is_func := false; (copy i := 0) for terms next i += 1 do (term) { @@ -4919,10 +4936,11 @@ autodiff_stmt_handler: type = { continue; } if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + is_func = true; continue; + } else { + postfix.error("AD: Unknown operator for standalone postfix expression. op: (term.get_op())$ expr: (postfix)$"); } - - is_func = false; } // Check for function call, everything else is not handled. @@ -4950,6 +4968,9 @@ autodiff_declaration_handler: type = { decl: meta::type_or_namespace_declaration; + is_type_context: bool = false; + diff_ad_type : std::string = ""; + operator=: (out this, ctx_: *autodiff_context, decl_: meta::type_or_namespace_declaration) = { autodiff_handler_base = (ctx_); decl = decl_; @@ -5025,13 +5046,35 @@ autodiff_declaration_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { - o.error("AD: Do not know how to handle object_declaration: (o.to_string())$"); + ad_name : std::string = "(o.name())$(ctx*.suffix)$"; + ad_type : std::string = ctx*.get_ad_type(o.type()); + + + if o.has_initializer() { + ad: autodiff_expression_handler = (ctx, "(o.name())$", ": " + o.type(), ": " + ad_type); + ad.primal_gen = false; + ad.pre_traverse(o.get_initializer()); + append(ad); + } + else { + diff = "(ad_name)$ : (ad_type)$;"; + } + + if is_type_context { + + diff_ad_type += "public (diff)$\n"; + } + else { + decl.add_member(diff); + } + diff = ""; } traverse: (override inout this, t: meta::type_declaration) = { ctx*.push_stack(t); ad: autodiff_declaration_handler = (ctx, t); + ad.is_type_context = true; for t.get_members() do (m) @@ -5041,6 +5084,12 @@ autodiff_declaration_handler: type = { } ctx*.pop_stack(); + + if !ad.diff_ad_type.empty() { + diff = "(t.name())$(ctx*.suffix)$ : type = {\n"; + diff += "(ad.diff_ad_type)$"; + diff += "}"; + } } From 803dfdef0633bc537315d45c72c488b3811507b1 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 10:08:07 +0200 Subject: [PATCH 32/54] Refactor of autodiff_expression_handler. The expression handler no longer generates the assignments. It stores the primal and forward expression. The assignments can now be generated with helper functions or by accessing the expressions. --- .../pure2-autodiff-higher-order.cpp | 38 +- .../pure2-autodiff-higher-order.cpp2.output | 26 +- .../test-results/pure2-autodiff.cpp | 56 +- .../test-results/pure2-autodiff.cpp2.output | 44 +- source/reflect.h | 1572 +++++++++-------- source/reflect.h2 | 265 +-- 6 files changed, 1062 insertions(+), 939 deletions(-) diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 6dede562f..023dd8eed 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -544,7 +544,9 @@ auto main() -> int; double r {0.0}; cpp2::taylor r_d {0.0}; auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; -auto temp_1 {x * y}; r_d = CPP2_UFCS(mul)(cpp2::move(temp_1_d), x_d, temp_1, x); + + auto temp_1 {x * y}; + r_d = CPP2_UFCS(mul)(cpp2::move(temp_1_d), x_d, temp_1, x); r = cpp2::move(temp_1) * x; return { std::move(r), std::move(r_d) }; } @@ -560,7 +562,9 @@ auto temp_1 {x * y}; r_d = CPP2_UFCS(mul)(cpp2::move(temp_1_d), x_d, temp_1, x); double r {0.0}; cpp2::taylor r_d {0.0}; auto temp_1_d {CPP2_UFCS(div)(x_d, y_d, x, y)}; -auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), y_d, temp_1, y); + + auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; + r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), y_d, temp_1, y); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); return { std::move(r), std::move(r_d) }; } @@ -569,7 +573,9 @@ auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = CPP2_UFCS(div)(c double r {0.0}; cpp2::taylor r_d {0.0}; auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; -auto temp_1 {x * y}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), x_d, temp_1, x); + + auto temp_1 {x * y}; + r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), x_d, temp_1, x); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); return { std::move(r), std::move(r_d) }; } @@ -577,9 +583,9 @@ auto temp_1 {x * y}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), x_d, temp_1, x); [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_add_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0}; -auto temp_1_d {x_d + y_d}; +cpp2::taylor temp_1_d {x_d + y_d}; - auto temp_1 {x + y}; + double temp_1 {x + y}; r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; @@ -588,9 +594,9 @@ auto temp_1_d {x_d + y_d}; [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0}; -auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; +cpp2::taylor temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; - auto temp_1 {x * y}; + double temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d); r = x + cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; @@ -606,22 +612,22 @@ auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0}; -auto temp_2 {func_d(x, x_d, y, y_d)}; +auto temp_1 {func_d(x, x_d, y, y_d)}; - auto temp_1 {temp_2.ret}; + cpp2::taylor temp_2_d {temp_1.ret_d}; - auto temp_1_d {cpp2::move(temp_2).ret_d}; - r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); - r = x * cpp2::move(temp_1); + double temp_2 {cpp2::move(temp_1).ret}; + r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_2_d), x, temp_2); + r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0}; -auto temp_1_d {x_d - y_d}; +cpp2::taylor temp_1_d {x_d - y_d}; - auto temp_1 {x - y}; + double temp_1 {x - y}; r_d = CPP2_UFCS(sin)(cpp2::move(temp_1_d), temp_1); r = sin(cpp2::move(temp_1)); return { std::move(r), std::move(r_d) }; @@ -765,10 +771,10 @@ int i_d {}; std::vector> v_d {}; std::vector v {}; - CPP2_UFCS(push_back)(v, x); CPP2_UFCS(push_back)(v_d, x_d); - CPP2_UFCS(push_back)(v, y); + CPP2_UFCS(push_back)(v, x); CPP2_UFCS(push_back)(v_d, y_d); + CPP2_UFCS(push_back)(v, y); r_d = { }; r = 0.0; { diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 7e4c57da7..1ace0113e 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -443,8 +443,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: _ = x_d + y_d; - temp_1: _ = x + y; + temp_1_d: cpp2::taylor = x_d + y_d; + temp_1: double = x + y; r_d = x_d.mul(temp_1_d, x, temp_1); r = x * temp_1; return; @@ -460,8 +460,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: _ = x_d.mul(y_d, x, y); - temp_1: _ = x * y; + temp_1_d: cpp2::taylor = x_d.mul(y_d, x, y); + temp_1: double = x * y; r_d = x_d + temp_1_d; r = x + temp_1; return; @@ -492,11 +492,11 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_2: _ = func_d(x, x_d, y, y_d); - temp_1: _ = temp_2.ret; - temp_1_d: _ = temp_2.ret_d; - r_d = x_d.mul(temp_1_d, x, temp_1); - r = x * temp_1; + temp_1: _ = func_d(x, x_d, y, y_d); + temp_2_d: cpp2::taylor = temp_1.ret_d; + temp_2: double = temp_1.ret; + r_d = x_d.mul(temp_2_d, x, temp_2); + r = x * temp_2; return; } @@ -510,8 +510,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: _ = x_d - y_d; - temp_1: _ = x - y; + temp_1_d: cpp2::taylor = x_d - y_d; + temp_1: double = x - y; r_d = temp_1_d.sin(temp_1); r = sin(temp_1); return; @@ -732,10 +732,10 @@ ad_test:/* @autodiff<"order=6"> @print */ type = { v_d: std::vector> = (); v: std::vector = (); - v.push_back(x); v_d.push_back(x_d); - v.push_back(y); + v.push_back(x); v_d.push_back(y_d); + v.push_back(y); r_d = (); r = 0.0; (copy t_d_iter: _ = v_d.begin(), ) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 82253538c..cbda55f01 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -615,7 +615,9 @@ return { std::move(ret), std::move(ret_d) }; double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); + + auto temp_1 {x * y}; + r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); r = cpp2::move(temp_1) * x; return { std::move(r), std::move(r_d) }; } @@ -631,7 +633,9 @@ auto temp_1 {x * y}; r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); double r {0.0}; double r_d {0.0}; auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; -auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + + auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; + r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); return { std::move(r), std::move(r_d) }; } @@ -640,7 +644,9 @@ auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; r_d = cpp2::move(temp_ double r {0.0}; double r_d {0.0}; auto temp_1_d {x * y_d + y * x_d}; -auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); + + auto temp_1 {x * y}; + r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); return { std::move(r), std::move(r_d) }; } @@ -648,9 +654,9 @@ auto temp_1 {x * y}; r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPE [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_d_ret{ double r {0.0}; double r_d {0.0}; -auto temp_1_d {x_d + y_d}; +double temp_1_d {x_d + y_d}; - auto temp_1 {x + y}; + double temp_1 {x + y}; r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; @@ -659,9 +665,9 @@ auto temp_1_d {x_d + y_d}; [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret{ double r {0.0}; double r_d {0.0}; -auto temp_1_d {x * y_d + y * x_d}; +double temp_1_d {x * y_d + y * x_d}; - auto temp_1 {x * y}; + double temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d); r = x + cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; @@ -677,35 +683,35 @@ auto temp_1_d {x * y_d + y * x_d}; [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret{ double r {0.0}; double r_d {0.0}; -auto temp_2 {func_d(x, x_d, y, y_d)}; +auto temp_1 {func_d(x, x_d, y, y_d)}; - auto temp_1 {temp_2.ret}; + double temp_2_d {temp_1.ret_d}; - auto temp_1_d {cpp2::move(temp_2).ret_d}; - r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; - r = x * cpp2::move(temp_1); + double temp_2 {cpp2::move(temp_1).ret}; + r_d = x * cpp2::move(temp_2_d) + temp_2 * x_d; + r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::func_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_call_d_ret{ double r {0.0}; double r_d {0.0}; -auto temp_2 {func_outer_d(x, x_d, y, y_d)}; +auto temp_1 {func_outer_d(x, x_d, y, y_d)}; - auto temp_1 {temp_2.ret}; + double temp_2_d {temp_1.ret_d}; - auto temp_1_d {cpp2::move(temp_2).ret_d}; - r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; - r = x * cpp2::move(temp_1); + double temp_2 {cpp2::move(temp_1).ret}; + r_d = x * cpp2::move(temp_2_d) + temp_2 * x_d; + r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret{ double r {0.0}; double r_d {0.0}; -auto temp_1_d {x_d - y_d}; +double temp_1_d {x_d - y_d}; - auto temp_1 {x - y}; + double temp_1 {x - y}; r_d = cos(temp_1) * cpp2::move(temp_1_d); r = sin(cpp2::move(temp_1)); return { std::move(r), std::move(r_d) }; @@ -849,10 +855,10 @@ int i_d {}; std::vector v_d {}; std::vector v {}; - CPP2_UFCS(push_back)(v, x); CPP2_UFCS(push_back)(v_d, x_d); - CPP2_UFCS(push_back)(v, y); + CPP2_UFCS(push_back)(v, x); CPP2_UFCS(push_back)(v_d, y_d); + CPP2_UFCS(push_back)(v, y); r_d = { }; r = 0.0; { @@ -900,13 +906,13 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; double r_d2 {0.0}; double r_d {0.0}; double r_d_d2 {0.0}; -auto temp_1_d2 {x * x_d_d2 + x_d * x_d2}; +double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; - auto temp_1 {x * x_d}; + double temp_1 {x * x_d}; - auto temp_2_d2 {x * x_d_d2 + x_d * x_d2}; + double temp_2_d2 {x * x_d_d2 + x_d * x_d2}; - auto temp_2 {x * x_d}; + double temp_2 {x * x_d}; r_d_d2 = cpp2::move(temp_1_d2) + cpp2::move(temp_2_d2); r_d = cpp2::move(temp_1) + cpp2::move(temp_2); r_d2 = x * x_d2 + x * x_d2; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 72ce41812..9095539ab 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -452,8 +452,8 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x_d + y_d; - temp_1: _ = x + y; + temp_1_d: double = x_d + y_d; + temp_1: double = x + y; r_d = x * temp_1_d + temp_1 * x_d; r = x * temp_1; return; @@ -469,8 +469,8 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x * y_d + y * x_d; - temp_1: _ = x * y; + temp_1_d: double = x * y_d + y * x_d; + temp_1: double = x * y; r_d = x_d + temp_1_d; r = x + temp_1; return; @@ -501,11 +501,11 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_2: _ = func_d(x, x_d, y, y_d); - temp_1: _ = temp_2.ret; - temp_1_d: _ = temp_2.ret_d; - r_d = x * temp_1_d + temp_1 * x_d; - r = x * temp_1; + temp_1: _ = func_d(x, x_d, y, y_d); + temp_2_d: double = temp_1.ret_d; + temp_2: double = temp_1.ret; + r_d = x * temp_2_d + temp_2 * x_d; + r = x * temp_2; return; } @@ -519,11 +519,11 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_2: _ = func_outer_d(x, x_d, y, y_d); - temp_1: _ = temp_2.ret; - temp_1_d: _ = temp_2.ret_d; - r_d = x * temp_1_d + temp_1 * x_d; - r = x * temp_1; + temp_1: _ = func_outer_d(x, x_d, y, y_d); + temp_2_d: double = temp_1.ret_d; + temp_2: double = temp_1.ret; + r_d = x * temp_2_d + temp_2 * x_d; + r = x * temp_2; return; } @@ -537,8 +537,8 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x_d - y_d; - temp_1: _ = x - y; + temp_1_d: double = x_d - y_d; + temp_1: double = x - y; r_d = cos(temp_1) * temp_1_d; r = sin(temp_1); return; @@ -759,10 +759,10 @@ ad_test:/* @autodiff @print */ type = { v_d: std::vector = (); v: std::vector = (); - v.push_back(x); v_d.push_back(x_d); - v.push_back(y); + v.push_back(x); v_d.push_back(y_d); + v.push_back(y); r_d = (); r = 0.0; (copy t_d_iter: _ = v_d.begin(), ) @@ -827,10 +827,10 @@ ad_test_twice:/* @autodiff @autodiff<"suffix=_d2"> @print */ type = out r_d_d2: double = 0.0, ) = { - temp_1_d2: _ = x * x_d_d2 + x_d * x_d2; - temp_1: _ = x * x_d; - temp_2_d2: _ = x * x_d_d2 + x_d * x_d2; - temp_2: _ = x * x_d; + temp_1_d2: double = x * x_d_d2 + x_d * x_d2; + temp_1: double = x * x_d; + temp_2_d2: double = x * x_d_d2 + x_d * x_d2; + temp_2: double = x * x_d; r_d_d2 = temp_1_d2 + temp_2_d2; r_d = temp_1 + temp_2; r_d2 = x * x_d2 + x * x_d2; diff --git a/source/reflect.h b/source/reflect.h index 1ac6d3839..d9758feb0 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -111,98 +111,98 @@ class simple_traverser; #line 3960 "reflect.h2" class autodiff_special_func; -#line 3989 "reflect.h2" +#line 3996 "reflect.h2" class autodiff_declaration_stack_item; -#line 4012 "reflect.h2" +#line 4019 "reflect.h2" class autodiff_context; -#line 4236 "reflect.h2" +#line 4244 "reflect.h2" class autodiff_handler_base; -#line 4250 "reflect.h2" +#line 4258 "reflect.h2" class autodiff_expression_handler; -#line 4686 "reflect.h2" +#line 4708 "reflect.h2" class autodiff_stmt_handler; -#line 4945 "reflect.h2" +#line 4980 "reflect.h2" class autodiff_declaration_handler; -#line 5150 "reflect.h2" +#line 5216 "reflect.h2" class expression_flags; -#line 5166 "reflect.h2" +#line 5232 "reflect.h2" class regex_token; -#line 5193 "reflect.h2" +#line 5259 "reflect.h2" class regex_token_check; -#line 5214 "reflect.h2" +#line 5280 "reflect.h2" class regex_token_code; -#line 5235 "reflect.h2" +#line 5301 "reflect.h2" class regex_token_empty; -#line 5253 "reflect.h2" +#line 5319 "reflect.h2" class regex_token_list; -#line 5305 "reflect.h2" +#line 5371 "reflect.h2" class parse_context_group_state; -#line 5366 "reflect.h2" +#line 5432 "reflect.h2" class parse_context_branch_reset_state; -#line 5409 "reflect.h2" +#line 5475 "reflect.h2" class parse_context; -#line 5810 "reflect.h2" +#line 5876 "reflect.h2" class generation_function_context; -#line 5828 "reflect.h2" +#line 5894 "reflect.h2" class generation_context; -#line 6027 "reflect.h2" +#line 6093 "reflect.h2" class alternative_token; -#line 6042 "reflect.h2" +#line 6108 "reflect.h2" class alternative_token_gen; -#line 6107 "reflect.h2" +#line 6173 "reflect.h2" class any_token; -#line 6124 "reflect.h2" +#line 6190 "reflect.h2" class atomic_group_token; -#line 6154 "reflect.h2" +#line 6220 "reflect.h2" class char_token; -#line 6269 "reflect.h2" +#line 6335 "reflect.h2" class class_token; -#line 6493 "reflect.h2" +#line 6559 "reflect.h2" class group_ref_token; -#line 6630 "reflect.h2" +#line 6696 "reflect.h2" class group_token; -#line 6977 "reflect.h2" +#line 7043 "reflect.h2" class lookahead_lookbehind_token; -#line 7072 "reflect.h2" +#line 7138 "reflect.h2" class range_token; -#line 7229 "reflect.h2" +#line 7295 "reflect.h2" class special_range_token; -#line 7315 "reflect.h2" +#line 7381 "reflect.h2" template class regex_generator; -#line 7572 "reflect.h2" +#line 7638 "reflect.h2" } } @@ -1651,26 +1651,28 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in class autodiff_special_func { public: std::string name; public: int n_args; - public: bool has_return; public: bool is_member; - public: std::string code; - public: std::string code_higher_order; + public: std::string code_primal; + public: std::string code_fwd; + public: std::string code_primal_higher_order; + public: std::string code_fwd_higher_order; - public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_ = "", cpp2::impl::in code_higher_order_ = ""); + public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in is_member_, cpp2::impl::in code_primal_ = "", cpp2::impl::in code_fwd_ = "", + cpp2::impl::in code_primal_higher_order_ = "", cpp2::impl::in code_fwd_higher_order_ = ""); -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" public: autodiff_special_func(autodiff_special_func const& that); -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" public: autodiff_special_func(autodiff_special_func&& that) noexcept; -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; -#line 3987 "reflect.h2" +#line 3994 "reflect.h2" }; class autodiff_declaration_stack_item { @@ -1684,49 +1686,48 @@ class autodiff_declaration_stack_item { using lookup_declaration_ret = std::vector; -#line 4001 "reflect.h2" +#line 4008 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4010 "reflect.h2" +#line 4017 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4024 "reflect.h2" +#line 4029 "reflect.h2" public: std::vector special_funcs { - autodiff_special_func("sin", 1, true, false, - "_rd_ = cos(_a1_) * _ad1_;\n" - "_r_ = sin(_a1_);\n", - "_rd_ = _ad1_.sin(_a1_);\n" - "_r_ = sin(_a1_);\n" + autodiff_special_func("sin", 1, false, + "sin(_a1_)", + "cos(_a1_) * _ad1_", + "sin(_a1_)", + "_ad1_.sin(_a1_)" ), - autodiff_special_func("cos", 1, true, false, - "_rd_ = -sin(_a1_) * _ad1_;\n" - "_r_ = cos(_a1_);\n", - "_rd_ = _ad1_.cos(_a1_);\n" - "_r_ = cos(_a1_);\n" - + autodiff_special_func("cos", 1, false, + "cos(_a1_)", + "-sin(_a1_) * _ad1_", + "cos(_a1_)", + "_ad1_.cos(_a1_)" ), - autodiff_special_func("exp", 1, true, false, - "_rd_ = exp(_a1_) * _ad1_;\n" - "_r_ = exp(_a1_);\n", - "_rd_ = _ad1_.exp(_a1_);\n" - "_r_ = exp(_a1_);\n" + autodiff_special_func("exp", 1, false, + "exp(_a1_)", + "exp(_a1_) * _ad1_", + "exp(_a1_)", + "_ad1_.exp(_a1_)" ), - autodiff_special_func("push_back", 1, false, true, - "_o_.push_back(_a1_);\n" - "_od_.push_back(_ad1_);\n")}; + autodiff_special_func("push_back", 1, true, + "_o_.push_back(_a1_);", + "_od_.push_back(_ad1_);")}; -#line 4050 "reflect.h2" +#line 4054 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4054 "reflect.h2" +#line 4058 "reflect.h2" public: std::string ad_type {"double"}; public: std::map> declaration_map {}; @@ -1734,62 +1735,62 @@ class autodiff_context { public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4076 "reflect.h2" +#line 4080 "reflect.h2" public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4087 "reflect.h2" +#line 4091 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4095 "reflect.h2" +#line 4099 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4104 "reflect.h2" +#line 4109 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; using lookup_function_declaration_ret = std::vector; -#line 4127 "reflect.h2" +#line 4132 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; -struct lookup_special_function_handling_ret { bool m; std::string code; }; +struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4137 "reflect.h2" - public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; +#line 4142 "reflect.h2" + public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4156 "reflect.h2" +#line 4164 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4164 "reflect.h2" +#line 4172 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4184 "reflect.h2" +#line 4192 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4194 "reflect.h2" +#line 4202 "reflect.h2" public: auto enter_function() & -> void; -#line 4198 "reflect.h2" +#line 4206 "reflect.h2" public: auto leave_function() & -> void; -#line 4201 "reflect.h2" +#line 4209 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4214 "reflect.h2" +#line 4222 "reflect.h2" public: auto pop_stack() & -> void; -#line 4229 "reflect.h2" +#line 4237 "reflect.h2" public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4234 "reflect.h2" +#line 4242 "reflect.h2" }; class autodiff_handler_base { @@ -1798,237 +1799,257 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4241 "reflect.h2" +#line 4249 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4245 "reflect.h2" +#line 4253 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4248 "reflect.h2" +#line 4256 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4254 "reflect.h2" +#line 4262 "reflect.h2" public: using base = simple_traverser; - public: std::string lhs; - public: std::string declare_p; - public: std::string declare_d; + public: std::string primal_expr {""}; + public: std::string fwd_expr {""}; - public: autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_ = "", cpp2::impl::in declare_d_ = ""); + public: autodiff_expression_handler(autodiff_context* ctx_); #line 4271 "reflect.h2" - public: auto gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first = false) & -> void; + public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; + +#line 4280 "reflect.h2" + public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; + +#line 4284 "reflect.h2" + public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); + + public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); #line 4290 "reflect.h2" + public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; + +#line 4294 "reflect.h2" + public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); + + public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); + + public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); + +#line 4303 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4299 "reflect.h2" +#line 4312 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4337 "reflect.h2" +#line 4352 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4459 "reflect.h2" - public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool; +#line 4472 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4492 "reflect.h2" +#line 4507 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4496 "reflect.h2" +#line 4511 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4500 "reflect.h2" +#line 4515 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4504 "reflect.h2" +#line 4519 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4508 "reflect.h2" +#line 4523 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4512 "reflect.h2" +#line 4527 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4516 "reflect.h2" +#line 4531 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4520 "reflect.h2" +#line 4535 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4524 "reflect.h2" +#line 4539 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4528 "reflect.h2" +#line 4543 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4532 "reflect.h2" +#line 4547 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4536 "reflect.h2" +#line 4551 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4560 "reflect.h2" +#line 4576 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4617 "reflect.h2" +#line 4631 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4621 "reflect.h2" +#line 4635 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4626 "reflect.h2" +#line 4640 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4653 "reflect.h2" +#line 4680 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4684 "reflect.h2" +#line 4706 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4690 "reflect.h2" +#line 4712 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4699 "reflect.h2" +#line 4721 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4704 "reflect.h2" +#line 4726 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4709 "reflect.h2" +#line 4731 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4727 "reflect.h2" +#line 4758 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4732 "reflect.h2" +#line 4763 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4737 "reflect.h2" +#line 4768 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4742 "reflect.h2" +#line 4773 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4750 "reflect.h2" +#line 4781 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4766 "reflect.h2" +#line 4798 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4813 "reflect.h2" +#line 4845 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4824 "reflect.h2" +#line 4856 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4852 "reflect.h2" +#line 4884 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4857 "reflect.h2" +#line 4889 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4861 "reflect.h2" +#line 4893 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4865 "reflect.h2" +#line 4897 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4869 "reflect.h2" +#line 4901 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4873 "reflect.h2" +#line 4905 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4877 "reflect.h2" +#line 4909 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4881 "reflect.h2" +#line 4913 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4885 "reflect.h2" +#line 4917 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4889 "reflect.h2" +#line 4921 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4893 "reflect.h2" +#line 4925 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4897 "reflect.h2" +#line 4929 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4901 "reflect.h2" +#line 4933 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4905 "reflect.h2" +#line 4937 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4910 "reflect.h2" +#line 4942 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4939 "reflect.h2" +#line 4974 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4943 "reflect.h2" +#line 4978 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4949 "reflect.h2" +#line 4984 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; + private: bool is_type_context {false}; + private: std::string diff_ad_type {""}; + public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4958 "reflect.h2" +#line 4996 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4963 "reflect.h2" +#line 5001 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5027 "reflect.h2" +#line 5065 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5032 "reflect.h2" +#line 5091 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5047 "reflect.h2" +#line 5113 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5052 "reflect.h2" +#line 5118 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5055 "reflect.h2" +#line 5121 "reflect.h2" }; -#line 5058 "reflect.h2" +#line 5124 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5146 "reflect.h2" +#line 5212 "reflect.h2" using error_func = std::function x)>; -#line 5150 "reflect.h2" +#line 5216 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2063,20 +2084,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5158 "reflect.h2" +#line 5224 "reflect.h2" }; -#line 5166 "reflect.h2" +#line 5232 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5174 "reflect.h2" +#line 5240 "reflect.h2" public: explicit regex_token(); -#line 5179 "reflect.h2" +#line 5245 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2088,103 +2109,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5185 "reflect.h2" +#line 5251 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5191 "reflect.h2" +#line 5257 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5197 "reflect.h2" +#line 5263 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5204 "reflect.h2" +#line 5270 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5208 "reflect.h2" +#line 5274 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5209 "reflect.h2" +#line 5275 "reflect.h2" }; -#line 5212 "reflect.h2" +#line 5278 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5218 "reflect.h2" +#line 5284 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5225 "reflect.h2" +#line 5291 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5229 "reflect.h2" +#line 5295 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5230 "reflect.h2" +#line 5296 "reflect.h2" }; -#line 5233 "reflect.h2" +#line 5299 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5239 "reflect.h2" +#line 5305 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5243 "reflect.h2" +#line 5309 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5247 "reflect.h2" +#line 5313 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5248 "reflect.h2" +#line 5314 "reflect.h2" }; -#line 5251 "reflect.h2" +#line 5317 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5257 "reflect.h2" +#line 5323 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5264 "reflect.h2" +#line 5330 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5270 "reflect.h2" +#line 5336 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5276 "reflect.h2" +#line 5342 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5284 "reflect.h2" +#line 5350 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2192,10 +2213,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5296 "reflect.h2" +#line 5362 "reflect.h2" }; -#line 5299 "reflect.h2" +#line 5365 "reflect.h2" // // Parse and generation context. // @@ -2211,33 +2232,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5319 "reflect.h2" +#line 5385 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5326 "reflect.h2" +#line 5392 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5338 "reflect.h2" +#line 5404 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5343 "reflect.h2" +#line 5409 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5347 "reflect.h2" +#line 5413 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5361 "reflect.h2" +#line 5427 "reflect.h2" }; -#line 5364 "reflect.h2" +#line 5430 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2250,25 +2271,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5382 "reflect.h2" +#line 5448 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5388 "reflect.h2" +#line 5454 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5395 "reflect.h2" +#line 5461 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5402 "reflect.h2" +#line 5468 "reflect.h2" }; -#line 5405 "reflect.h2" +#line 5471 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2284,7 +2305,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5421 "reflect.h2" +#line 5487 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2292,64 +2313,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5432 "reflect.h2" +#line 5498 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5445 "reflect.h2" +#line 5511 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5453 "reflect.h2" +#line 5519 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5457 "reflect.h2" +#line 5523 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5461 "reflect.h2" +#line 5527 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5473 "reflect.h2" +#line 5539 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5480 "reflect.h2" +#line 5546 "reflect.h2" public: auto next_alternative() & -> void; -#line 5486 "reflect.h2" +#line 5552 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5492 "reflect.h2" +#line 5558 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5496 "reflect.h2" +#line 5562 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5507 "reflect.h2" +#line 5573 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5511 "reflect.h2" +#line 5577 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5517 "reflect.h2" +#line 5583 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5521 "reflect.h2" +#line 5587 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5528 "reflect.h2" +#line 5594 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5539 "reflect.h2" +#line 5605 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2357,51 +2378,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5583 "reflect.h2" +#line 5649 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5595 "reflect.h2" +#line 5661 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5608 "reflect.h2" +#line 5674 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5631 "reflect.h2" +#line 5697 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5648 "reflect.h2" +#line 5714 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5669 "reflect.h2" +#line 5735 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5679 "reflect.h2" +#line 5745 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5683 "reflect.h2" +#line 5749 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5739 "reflect.h2" +#line 5805 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5778 "reflect.h2" +#line 5844 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5793 "reflect.h2" +#line 5859 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2413,10 +2434,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5804 "reflect.h2" +#line 5870 "reflect.h2" }; -#line 5807 "reflect.h2" +#line 5873 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2426,16 +2447,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5821 "reflect.h2" +#line 5887 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5824 "reflect.h2" +#line 5890 "reflect.h2" }; -#line 5827 "reflect.h2" +#line 5893 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2455,68 +2476,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5849 "reflect.h2" +#line 5915 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5855 "reflect.h2" +#line 5921 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5864 "reflect.h2" +#line 5930 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5875 "reflect.h2" +#line 5941 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5882 "reflect.h2" +#line 5948 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5902 "reflect.h2" +#line 5968 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5912 "reflect.h2" +#line 5978 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5935 "reflect.h2" +#line 6001 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5943 "reflect.h2" +#line 6009 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5947 "reflect.h2" +#line 6013 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 5953 "reflect.h2" +#line 6019 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 5959 "reflect.h2" +#line 6025 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 5969 "reflect.h2" +#line 6035 "reflect.h2" public: auto finish_context() & -> void; -#line 5977 "reflect.h2" +#line 6043 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 5983 "reflect.h2" +#line 6049 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 5987 "reflect.h2" +#line 6053 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 5991 "reflect.h2" +#line 6057 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6015 "reflect.h2" +#line 6081 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2524,7 +2545,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6021 "reflect.h2" +#line 6087 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2544,27 +2565,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6040 "reflect.h2" +#line 6106 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6046 "reflect.h2" +#line 6112 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6053 "reflect.h2" +#line 6119 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6070 "reflect.h2" +#line 6136 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6077 "reflect.h2" +#line 6143 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6090 "reflect.h2" +#line 6156 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2572,19 +2593,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6102 "reflect.h2" +#line 6168 "reflect.h2" }; -#line 6105 "reflect.h2" +#line 6171 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6111 "reflect.h2" +#line 6177 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6115 "reflect.h2" +#line 6181 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2592,7 +2613,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6120 "reflect.h2" +#line 6186 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2600,17 +2621,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6128 "reflect.h2" +#line 6194 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6139 "reflect.h2" +#line 6205 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6147 "reflect.h2" +#line 6213 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2618,7 +2639,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6150 "reflect.h2" +#line 6216 "reflect.h2" }; // Regex syntax: a @@ -2626,34 +2647,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6158 "reflect.h2" +#line 6224 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6167 "reflect.h2" +#line 6233 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6173 "reflect.h2" +#line 6239 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6177 "reflect.h2" +#line 6243 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6200 "reflect.h2" +#line 6266 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6221 "reflect.h2" +#line 6287 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6239 "reflect.h2" +#line 6305 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6254 "reflect.h2" +#line 6320 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6260 "reflect.h2" +#line 6326 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2661,33 +2682,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6264 "reflect.h2" +#line 6330 "reflect.h2" }; -#line 6267 "reflect.h2" +#line 6333 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6273 "reflect.h2" +#line 6339 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6285 "reflect.h2" +#line 6351 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6411 "reflect.h2" +#line 6477 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6420 "reflect.h2" +#line 6486 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6425 "reflect.h2" +#line 6491 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2695,20 +2716,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6432 "reflect.h2" +#line 6498 "reflect.h2" }; -#line 6435 "reflect.h2" +#line 6501 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6476 "reflect.h2" +#line 6542 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6487 "reflect.h2" +#line 6553 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2718,20 +2739,20 @@ class class_token class group_ref_token : public regex_token { -#line 6497 "reflect.h2" +#line 6563 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6509 "reflect.h2" +#line 6575 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6610 "reflect.h2" +#line 6676 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6614 "reflect.h2" +#line 6680 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2739,10 +2760,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6617 "reflect.h2" +#line 6683 "reflect.h2" }; -#line 6620 "reflect.h2" +#line 6686 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2756,29 +2777,29 @@ class group_ref_token class group_token : public regex_token { -#line 6634 "reflect.h2" +#line 6700 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6656 "reflect.h2" +#line 6722 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6670 "reflect.h2" +#line 6736 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6829 "reflect.h2" +#line 6895 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6837 "reflect.h2" +#line 6903 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6855 "reflect.h2" +#line 6921 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6886 "reflect.h2" +#line 6952 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2787,25 +2808,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6893 "reflect.h2" +#line 6959 "reflect.h2" }; -#line 6896 "reflect.h2" +#line 6962 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6937 "reflect.h2" +#line 7003 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 6957 "reflect.h2" +#line 7023 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 6973 "reflect.h2" +#line 7039 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2813,20 +2834,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 6981 "reflect.h2" +#line 7047 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 6990 "reflect.h2" +#line 7056 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7001 "reflect.h2" +#line 7067 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7008 "reflect.h2" +#line 7074 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2834,26 +2855,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7011 "reflect.h2" +#line 7077 "reflect.h2" }; -#line 7014 "reflect.h2" +#line 7080 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7042 "reflect.h2" +#line 7108 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7070 "reflect.h2" +#line 7136 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7076 "reflect.h2" +#line 7142 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2863,22 +2884,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7156 "reflect.h2" +#line 7222 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7168 "reflect.h2" +#line 7234 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7181 "reflect.h2" +#line 7247 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7200 "reflect.h2" +#line 7266 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7210 "reflect.h2" +#line 7276 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7221 "reflect.h2" +#line 7287 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2886,16 +2907,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7224 "reflect.h2" +#line 7290 "reflect.h2" }; -#line 7227 "reflect.h2" +#line 7293 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7233 "reflect.h2" +#line 7299 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2904,7 +2925,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7263 "reflect.h2" +#line 7329 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2913,14 +2934,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7285 "reflect.h2" +#line 7351 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7307 "reflect.h2" +#line 7373 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2941,24 +2962,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7330 "reflect.h2" +#line 7396 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7365 "reflect.h2" +#line 7431 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7379 "reflect.h2" +#line 7445 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7391 "reflect.h2" +#line 7457 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7446 "reflect.h2" +#line 7512 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2969,7 +2990,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7572 "reflect.h2" +#line 7638 "reflect.h2" } } @@ -7533,76 +7554,85 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // autodiff - stub // -#line 3969 "reflect.h2" - autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in has_return_, cpp2::impl::in is_member_, cpp2::impl::in code_, cpp2::impl::in code_higher_order_) +#line 3970 "reflect.h2" + autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in is_member_, cpp2::impl::in code_primal_, cpp2::impl::in code_fwd_, + cpp2::impl::in code_primal_higher_order_, cpp2::impl::in code_fwd_higher_order_) : name{ name_ } , n_args{ n_args_ } - , has_return{ has_return_ } , is_member{ is_member_ } - , code{ code_ } - , code_higher_order{ code_higher_order_ }{ + , code_primal{ code_primal_ } + , code_fwd{ code_fwd_ } + , code_primal_higher_order{ code_primal_higher_order_ } + , code_fwd_higher_order{ code_fwd_higher_order_ }{ -#line 3977 "reflect.h2" - if (CPP2_UFCS(empty)(code_higher_order)) { - code_higher_order = code; +#line 3981 "reflect.h2" + if (CPP2_UFCS(empty)(code_primal_higher_order)) { + code_primal_higher_order = code_primal; + } + if (CPP2_UFCS(empty)(code_fwd_higher_order)) { + code_fwd_higher_order = code_fwd; } } -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) : name{ that.name } , n_args{ that.n_args } - , has_return{ that.has_return } , is_member{ that.is_member } - , code{ that.code } - , code_higher_order{ that.code_higher_order }{} -#line 3982 "reflect.h2" + , code_primal{ that.code_primal } + , code_fwd{ that.code_fwd } + , code_primal_higher_order{ that.code_primal_higher_order } + , code_fwd_higher_order{ that.code_fwd_higher_order }{} +#line 3989 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { name = that.name; n_args = that.n_args; - has_return = that.has_return; is_member = that.is_member; - code = that.code; - code_higher_order = that.code_higher_order; + code_primal = that.code_primal; + code_fwd = that.code_fwd; + code_primal_higher_order = that.code_primal_higher_order; + code_fwd_higher_order = that.code_fwd_higher_order; return *this; } -#line 3982 "reflect.h2" +#line 3989 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept : name{ std::move(that).name } , n_args{ std::move(that).n_args } - , has_return{ std::move(that).has_return } , is_member{ std::move(that).is_member } - , code{ std::move(that).code } - , code_higher_order{ std::move(that).code_higher_order }{} -#line 3982 "reflect.h2" + , code_primal{ std::move(that).code_primal } + , code_fwd{ std::move(that).code_fwd } + , code_primal_higher_order{ std::move(that).code_primal_higher_order } + , code_fwd_higher_order{ std::move(that).code_fwd_higher_order }{} +#line 3989 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { name = std::move(that).name; n_args = std::move(that).n_args; - has_return = std::move(that).has_return; is_member = std::move(that).is_member; - code = std::move(that).code; - code_higher_order = std::move(that).code_higher_order; + code_primal = std::move(that).code_primal; + code_fwd = std::move(that).code_fwd; + code_primal_higher_order = std::move(that).code_primal_higher_order; + code_fwd_higher_order = std::move(that).code_fwd_higher_order; return *this; }// Default copy. -#line 3984 "reflect.h2" +#line 3991 "reflect.h2" [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ - return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; + return name == o.name && n_args == o.n_args && is_member == o.is_member; } -#line 3990 "reflect.h2" +#line 3997 "reflect.h2" // namespace + type name -#line 3996 "reflect.h2" +#line 4003 "reflect.h2" autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) : full_name{ full_name_ } , decl{ decl_ }{ -#line 3999 "reflect.h2" +#line 4006 "reflect.h2" } -#line 4001 "reflect.h2" +#line 4008 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 4002 "reflect.h2" +#line 4009 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -7623,32 +7653,30 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , diff_request{ std::move(that).diff_request } , diff_done{ std::move(that).diff_done }{} -#line 4015 "reflect.h2" +#line 4022 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. - // _r_ : name of the return value. - // _rd_ : name of derivative return value. // _a1_ : First argument value // _ad1_: First derivative argument value // _a2_ : Second argument value // _ad2_: Second derivative argument value - /* has_return = */ /* is_member = */ + /* is_member = */ -#line 4032 "reflect.h2" - /* has_return = */ /* is_member = */ +#line 4037 "reflect.h2" + /* is_member = */ -#line 4039 "reflect.h2" - /* has_return = */ /* is_member = */ +#line 4043 "reflect.h2" + /* is_member = */ -#line 4045 "reflect.h2" - /* has_return = */ /* is_member = */ +#line 4049 "reflect.h2" + /* is_member = */ -#line 4053 "reflect.h2" +#line 4057 "reflect.h2" // Members depending on order -#line 4059 "reflect.h2" +#line 4063 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -7666,7 +7694,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4076 "reflect.h2" +#line 4080 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7678,19 +7706,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4087 "reflect.h2" +#line 4091 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4089 "reflect.h2" +#line 4093 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } // TODO: Have the proper type declaration here. -#line 4095 "reflect.h2" +#line 4099 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ + // TODO: Lookup if type is a known type and if it has AD values. if (order == 1) { return type; // Same type for now for order 1 } @@ -7698,10 +7727,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(type, "double", ad_type); } -#line 4104 "reflect.h2" +#line 4109 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4105 "reflect.h2" +#line 4110 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7724,10 +7753,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4127 "reflect.h2" +#line 4132 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4128 "reflect.h2" +#line 4133 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7737,30 +7766,34 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4137 "reflect.h2" - [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in has_return, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ +#line 4142 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; - cpp2::impl::deferred_init code; -#line 4138 "reflect.h2" - autodiff_special_func lookup {func_name, n_args, has_return, is_member}; + cpp2::impl::deferred_init code_primal; + cpp2::impl::deferred_init code_fwd; +#line 4143 "reflect.h2" + autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); - code.construct(""); + code_primal.construct(""); + code_fwd.construct(""); for ( auto const& func : special_funcs ) { if (CPP2_UFCS(is_match)(func, lookup)) { m.value() = true; if (is_taylor()) { - code.value() = func.code_higher_order; + code_primal.value() = func.code_primal_higher_order; + code_fwd.value() = func.code_fwd_higher_order; } else { - code.value() = func.code; + code_primal.value() = func.code_primal; + code_fwd.value() = func.code_fwd; } - return { std::move(m.value()), std::move(code.value()) }; + return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } - }return { std::move(m.value()), std::move(code.value()) }; + }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4156 "reflect.h2" +#line 4164 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -7769,7 +7802,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4164 "reflect.h2" +#line 4172 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -7790,7 +7823,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4184 "reflect.h2" +#line 4192 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -7801,16 +7834,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4194 "reflect.h2" +#line 4202 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4198 "reflect.h2" +#line 4206 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4201 "reflect.h2" +#line 4209 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -7824,7 +7857,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4214 "reflect.h2" +#line 4222 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -7840,68 +7873,79 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4229 "reflect.h2" +#line 4237 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4241 "reflect.h2" +#line 4249 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4243 "reflect.h2" +#line 4251 "reflect.h2" } -#line 4241 "reflect.h2" +#line 4249 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4243 "reflect.h2" +#line 4251 "reflect.h2" } -#line 4245 "reflect.h2" +#line 4253 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4260 "reflect.h2" - autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_, cpp2::impl::in lhs_, cpp2::impl::in declare_p_, cpp2::impl::in declare_d_) +#line 4267 "reflect.h2" + autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } - , autodiff_handler_base{ ctx_ } - , lhs{ lhs_ } - , declare_p{ declare_p_ } - , declare_d{ declare_d_ }{ + , autodiff_handler_base{ ctx_ }{ -#line 4266 "reflect.h2" - if (CPP2_UFCS(empty)(declare_d) && !(CPP2_UFCS(empty)(declare_p))) { - declare_d = declare_p; - } +#line 4269 "reflect.h2" } #line 4271 "reflect.h2" - auto autodiff_expression_handler::gen_lhs_assignment(cpp2::impl::in prim, cpp2::impl::in fwd, cpp2::impl::in primal_first) & -> void{ - std::string lhs_d {lhs + (*cpp2::impl::assert_not_null(ctx)).suffix}; - if (lhs == "_") { - // TODO: Maybe improve discard handling - lhs_d = lhs; + [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ + if ("_" == lhs) { + return lhs; } - - auto fwd_str {"" + cpp2::to_string(cpp2::move(lhs_d)) + " " + cpp2::to_string(declare_d) + " = " + cpp2::to_string(fwd) + ";\n"}; - auto primal_str {"" + cpp2::to_string(lhs) + " " + cpp2::to_string(declare_p) + " = " + cpp2::to_string(prim) + ";\n"}; - - if (primal_first) { - diff += primal_str; - } - diff += cpp2::move(fwd_str); - if (!(primal_first)) { - diff += cpp2::move(primal_str); + else { + return lhs + (*cpp2::impl::assert_not_null(ctx)).suffix; } } +#line 4280 "reflect.h2" + auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ + diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; + diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; + } +#line 4284 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { + return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } +#line 4286 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { + return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } + #line 4290 "reflect.h2" + auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ + diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; + diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; + } +#line 4294 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } +#line 4296 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } +#line 4298 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } + +#line 4303 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7911,7 +7955,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return args; } -#line 4299 "reflect.h2" +#line 4312 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7930,9 +7974,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return "error"; } - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - autodiff_expression_handler ad {ctx, t, ":"}; // TODO: get type of expression + autodiff_expression_handler ad {ctx}; ad.pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(CPP2_UFCS(get_terms)(cpp2::move(bin_expr))))); + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); return t; @@ -7941,16 +7986,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar // Nothing special. A regular expression. auto expr {term}; - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - autodiff_expression_handler ad {ctx, t, ":"}; // TODO: get type of expression + autodiff_expression_handler ad {ctx}; ad.pre_traverse(cpp2::move(expr)); + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); return t; }} } -#line 4337 "reflect.h2" +#line 4352 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -7958,7 +8004,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4343 "reflect.h2" +#line 4358 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -7972,7 +8018,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4355 "reflect.h2" +#line 4370 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -7995,7 +8041,7 @@ auto i{0}; { auto i{0}; -#line 4376 "reflect.h2" +#line 4391 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8020,12 +8066,8 @@ auto i{0}; } while (false); i += 1; } } -#line 4399 "reflect.h2" - auto r_arg {lhs}; - if (!(has_return)) { - r_arg = ""; - } - if (handle_special_function(object, cpp2::move(object_d), function_name, args, cpp2::move(r_arg))) { +#line 4414 "reflect.h2" + if (handle_special_function(object, cpp2::move(object_d), function_name, args)) { return ; } @@ -8073,7 +8115,9 @@ auto i{0}; std::string ret_name_d {ret_name + (*cpp2::impl::assert_not_null(ctx)).suffix}; - gen_lhs_assignment("" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + "", "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + "", true);/* switch order = */ + primal_expr = "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + ""; + fwd_expr = "" + cpp2::to_string(cpp2::move(ret_temp)) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + ""; + // TODO: check reverse order CPP2_UFCS(add_for_differentiation)((*cpp2::impl::assert_not_null(ctx)), CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(functions), 0)); } @@ -8081,100 +8125,102 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4459 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args, cpp2::impl::in ret) & -> bool{ +#line 4472 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ - auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(ret)), !(CPP2_UFCS(empty)(object)))}; + auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; if (!(r.m)) { return false; // No match } // Have a match, do the replacement - std::string code {""}; - code = cpp2::move(r).code;// TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + std::string code_primal {r.code_primal}; + std::string code_fwd {cpp2::move(r).code_fwd}; if (!(CPP2_UFCS(empty)(object))) { - code = string_util::replace_all(code, "_o_", object); - code = string_util::replace_all(code, "_od_", object_d); - } + code_primal = string_util::replace_all(code_primal, "_o_", object); + code_primal = string_util::replace_all(code_primal, "_od_", object_d); - if (!(CPP2_UFCS(empty)(ret))) { - code = string_util::replace_all(code, "_r_", ret); - code = string_util::replace_all(code, "_rd_", ret + (*cpp2::impl::assert_not_null(ctx)).suffix); + code_fwd = string_util::replace_all(code_fwd, "_o_", object); + code_fwd = string_util::replace_all(code_fwd, "_od_", object_d); } { auto i{1}; -#line 4482 "reflect.h2" +#line 4493 "reflect.h2" for ( auto const& arg : args ) { - code = string_util::replace_all(code, "_a" + cpp2::to_string(i) + "_", arg); - code = string_util::replace_all(code, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); + code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg); + code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); + + code_fwd = string_util::replace_all(code_fwd, "_a" + cpp2::to_string(i) + "_", arg); + code_fwd = string_util::replace_all(code_fwd, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); } } -#line 4487 "reflect.h2" - diff += cpp2::move(code); +#line 4501 "reflect.h2" + primal_expr = cpp2::move(code_primal); + fwd_expr = cpp2::move(code_fwd); return true; } -#line 4492 "reflect.h2" +#line 4507 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4496 "reflect.h2" +#line 4511 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4500 "reflect.h2" +#line 4515 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4504 "reflect.h2" +#line 4519 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4508 "reflect.h2" +#line 4523 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4512 "reflect.h2" +#line 4527 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4516 "reflect.h2" +#line 4531 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4520 "reflect.h2" +#line 4535 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4524 "reflect.h2" +#line 4539 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4528 "reflect.h2" +#line 4543 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4532 "reflect.h2" +#line 4547 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4536 "reflect.h2" +#line 4551 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8196,10 +8242,11 @@ auto i{1}; first = false; } - gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); + primal_expr = cpp2::move(primal); + fwd_expr = cpp2::move(fwd); } -#line 4560 "reflect.h2" +#line 4576 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8238,18 +8285,16 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4599 "reflect.h2" +#line 4615 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { - // Last item - gen_lhs_assignment(cpp2::move(primal), cpp2::move(fwd)); + primal_expr = cpp2::move(primal); + fwd_expr = cpp2::move(fwd); } else { // Temporary auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).suffix}; - // TODO: Get type of expression, in order to define the type of t. - diff += "" + cpp2::to_string(t_d) + " := " + cpp2::to_string(cpp2::move(fwd)) + ";"; - diff += "" + cpp2::to_string(t) + " := " + cpp2::to_string(cpp2::move(primal)) + ";"; + gen_declaration(t, t_d, cpp2::move(primal), cpp2::move(fwd), "", ""); arg_a = cpp2::move(t); arg_a_d = cpp2::move(t_d); @@ -8257,73 +8302,81 @@ auto i{1}; } } -#line 4617 "reflect.h2" +#line 4631 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4621 "reflect.h2" +#line 4635 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4626 "reflect.h2" +#line 4640 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; - auto is_func {true}; + auto is_func {false}; { auto i{0}; -#line 4633 "reflect.h2" +#line 4647 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; } if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + is_func = true; continue; } - - is_func = false; + else { + CPP2_UFCS(error)(postfix, "AD: Unknown operator for postfix expression. op: " + cpp2::to_string(CPP2_UFCS(get_op)(term)) + " expr: " + cpp2::to_string(postfix) + ""); + } } while (false); i += 1; } } - // Check for function call, everything else is not handled. -#line 4645 "reflect.h2" - if (!((cpp2::move(is_func)))) { - CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); - return ; +#line 4660 "reflect.h2" + if (cpp2::move(is_func)) { + handle_function_call(postfix, true); } + else { + // Member access + + auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; + std::string obj_name {CPP2_UFCS(to_string)(cpp2::move(primary))}; + std::string obj_name_d {obj_name + (*cpp2::impl::assert_not_null(ctx)).suffix}; + std::string obj_access {""}; - handle_function_call(postfix, true); + for ( auto const& term : cpp2::move(terms) ) { + obj_access += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)); + } + + primal_expr = "" + cpp2::to_string(cpp2::move(obj_name)) + cpp2::to_string(obj_access) + ""; + fwd_expr = "" + cpp2::to_string(cpp2::move(obj_name_d)) + cpp2::to_string(cpp2::move(obj_access)) + ""; + } } -#line 4653 "reflect.h2" +#line 4680 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { - gen_lhs_assignment(CPP2_UFCS(to_string)(primary), CPP2_UFCS(to_string)(primary) + (*cpp2::impl::assert_not_null(ctx)).suffix); + primal_expr = CPP2_UFCS(to_string)(primary); + fwd_expr = CPP2_UFCS(to_string)(primary) + (*cpp2::impl::assert_not_null(ctx)).suffix; } else {if (CPP2_UFCS(is_expression_list)(primary)) { if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { - gen_lhs_assignment("()", "()"); + primal_expr = "()"; + fwd_expr = "()"; } else { CPP2_UFCS(error)(primary, "AD: Do not know how to handle non empty expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); } } else {if (CPP2_UFCS(is_literal)(primary)) { - auto literal_str {CPP2_UFCS(to_string)(primary)}; - - std::string ad_init {"()"}; - - // TODO: Determine propre zero initializer from type of literal. - if (declare_d == ":" || declare_d == ": _") { - ad_init = CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; - } - gen_lhs_assignment(CPP2_UFCS(to_string)(primary), cpp2::move(ad_init)); + primal_expr = CPP2_UFCS(to_string)(primary); + fwd_expr = "()"; } else {if (CPP2_UFCS(is_declaration)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -8333,59 +8386,68 @@ auto i{0}; }}}} } -#line 4694 "reflect.h2" +#line 4716 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4697 "reflect.h2" +#line 4719 "reflect.h2" } -#line 4699 "reflect.h2" +#line 4721 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4704 "reflect.h2" +#line 4726 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4709 "reflect.h2" +#line 4731 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + std::string prim_init {""}; + std::string fwd_init {""}; + if (CPP2_UFCS(has_initializer)(o)) { - autodiff_expression_handler ad {ctx, cpp2::move(lhs), ": " + cpp2::move(type), ": " + cpp2::move(ad_type)}; + autodiff_expression_handler ad {ctx}; CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(o)); - append(cpp2::move(ad)); - } - else { - diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(cpp2::move(ad_type)) + ";\n"; - diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + ";\n"; + append(ad); + + prim_init = " = " + ad.primal_expr; + fwd_init = " = " + ad.fwd_expr; + + if (type == "_" && cpp2::move(ad).fwd_expr == "()") { + // Special handling for auto initialization from a literal. + fwd_init = " = " + CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; + } } + diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(cpp2::move(ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; + diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; } -#line 4727 "reflect.h2" +#line 4758 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4732 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4737 "reflect.h2" +#line 4768 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4742 "reflect.h2" +#line 4773 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8393,15 +8455,16 @@ auto i{0}; diff += "}\n"; } -#line 4750 "reflect.h2" +#line 4781 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. // TODO: Remove assumptions // - Return expression is always active. (Look this up in mf or so.) // - Return was converted to a two parameter return with the name r. - autodiff_expression_handler ad {ctx, "r"}; + autodiff_expression_handler ad {ctx}; ad.pre_traverse(CPP2_UFCS(get_expression)(stmt)); + CPP2_UFCS(gen_assignment)(ad, "r"); append(cpp2::move(ad)); } else { @@ -8409,7 +8472,7 @@ auto i{0}; } } -#line 4766 "reflect.h2" +#line 4798 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8456,7 +8519,7 @@ auto i{0}; }} } -#line 4813 "reflect.h2" +#line 4845 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8468,7 +8531,7 @@ auto i{0}; } } -#line 4824 "reflect.h2" +#line 4856 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ if (CPP2_UFCS(is_simple_assignment)(expr)) { @@ -8487,9 +8550,9 @@ auto i{0}; // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each // @ is one of a list of operators at the same grammar precedence - autodiff_expression_handler h {ctx, CPP2_UFCS(to_string)(cpp2::move(lhs))}; + autodiff_expression_handler h {ctx}; CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - + CPP2_UFCS(gen_assignment)(h, CPP2_UFCS(to_string)(cpp2::move(lhs))); append(cpp2::move(h)); } else { @@ -8497,133 +8560,136 @@ auto i{0}; } } -#line 4852 "reflect.h2" +#line 4884 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4857 "reflect.h2" +#line 4889 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4861 "reflect.h2" +#line 4893 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4865 "reflect.h2" +#line 4897 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4869 "reflect.h2" +#line 4901 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4873 "reflect.h2" +#line 4905 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4877 "reflect.h2" +#line 4909 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4881 "reflect.h2" +#line 4913 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4885 "reflect.h2" +#line 4917 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4889 "reflect.h2" +#line 4921 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4893 "reflect.h2" +#line 4925 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4897 "reflect.h2" +#line 4929 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4901 "reflect.h2" +#line 4933 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4905 "reflect.h2" +#line 4937 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4910 "reflect.h2" +#line 4942 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; - auto is_func {true}; + auto is_func {false}; { auto i{0}; -#line 4917 "reflect.h2" +#line 4949 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; } if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + is_func = true; continue; + }else { + CPP2_UFCS(error)(postfix, "AD: Unknown operator for standalone postfix expression. op: " + cpp2::to_string(CPP2_UFCS(get_op)(term)) + " expr: " + cpp2::to_string(postfix) + ""); } - - is_func = false; } while (false); i += 1; } } // Check for function call, everything else is not handled. -#line 4929 "reflect.h2" +#line 4962 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; } - autodiff_expression_handler ad {ctx, ""}; + autodiff_expression_handler ad {ctx}; CPP2_UFCS(handle_function_call)(ad, postfix, false); + ad.diff += ad.fwd_expr + "\n"; + ad.diff += ad.primal_expr + "\n"; append(cpp2::move(ad)); } -#line 4939 "reflect.h2" +#line 4974 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4953 "reflect.h2" +#line 4991 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4956 "reflect.h2" +#line 4994 "reflect.h2" } -#line 4958 "reflect.h2" +#line 4996 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4963 "reflect.h2" +#line 5001 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8667,10 +8733,10 @@ auto i{0}; return ; } -#line 5007 "reflect.h2" +#line 5045 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5010 "reflect.h2" +#line 5048 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8687,15 +8753,37 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5027 "reflect.h2" +#line 5065 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ - CPP2_UFCS(error)(o, "AD: Do not know how to handle object_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(o)) + ""); + std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; + std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; + std::string ad_init {""}; + + if (CPP2_UFCS(has_initializer)(o)) { + autodiff_expression_handler ad {ctx}; + CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(o)); + + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(empty)(ad.diff)) ) { cpp2::cpp2_default.report_violation(""); } + ad_init = " = " + cpp2::move(ad).fwd_expr; + } + + diff = "" + cpp2::to_string(cpp2::move(ad_name)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + cpp2::to_string(cpp2::move(ad_init)) + ";"; + + if (is_type_context) { + + diff_ad_type += "public " + cpp2::to_string(diff) + "\n"; + } + else { + CPP2_UFCS(add_member)(decl, diff); + } + diff = ""; } -#line 5032 "reflect.h2" +#line 5091 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; + ad.is_type_context = true; for ( auto const& m : CPP2_UFCS(get_members)(t) ) @@ -8705,19 +8793,25 @@ auto i{0}; } CPP2_UFCS(pop_stack)((*cpp2::impl::assert_not_null(ctx))); + + if (!(CPP2_UFCS(empty)(ad.diff_ad_type))) { + diff = "" + cpp2::to_string(CPP2_UFCS(name)(t)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : type = {\n"; + diff += "" + cpp2::to_string(cpp2::move(ad).diff_ad_type) + ""; + diff += "}"; + } } -#line 5047 "reflect.h2" +#line 5113 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5052 "reflect.h2" +#line 5118 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5058 "reflect.h2" +#line 5124 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8753,7 +8847,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5094 "reflect.h2" +#line 5160 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8882,7 +8976,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5132 "reflect.h2" +#line 5198 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8898,11 +8992,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5148 "reflect.h2" +#line 5214 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5152 "reflect.h2" +#line 5218 "reflect.h2" // mod: i // mod: m // mod: s @@ -8910,116 +9004,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5161 "reflect.h2" +#line 5227 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5170 "reflect.h2" +#line 5236 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5172 "reflect.h2" +#line 5238 "reflect.h2" } -#line 5174 "reflect.h2" +#line 5240 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5176 "reflect.h2" +#line 5242 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5182 "reflect.h2" +#line 5248 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5183 "reflect.h2" +#line 5249 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5184 "reflect.h2" +#line 5250 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5199 "reflect.h2" +#line 5265 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5202 "reflect.h2" +#line 5268 "reflect.h2" } -#line 5204 "reflect.h2" +#line 5270 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5208 "reflect.h2" +#line 5274 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5220 "reflect.h2" +#line 5286 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5223 "reflect.h2" +#line 5289 "reflect.h2" } -#line 5225 "reflect.h2" +#line 5291 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5229 "reflect.h2" +#line 5295 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5239 "reflect.h2" +#line 5305 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5241 "reflect.h2" +#line 5307 "reflect.h2" } -#line 5243 "reflect.h2" +#line 5309 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5247 "reflect.h2" +#line 5313 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5259 "reflect.h2" +#line 5325 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5262 "reflect.h2" +#line 5328 "reflect.h2" } -#line 5264 "reflect.h2" +#line 5330 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5270 "reflect.h2" +#line 5336 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5276 "reflect.h2" +#line 5342 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9028,7 +9122,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5284 "reflect.h2" +#line 5350 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9044,7 +9138,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5312 "reflect.h2" +#line 5378 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9052,14 +9146,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5320 "reflect.h2" +#line 5386 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5327 "reflect.h2" +#line 5393 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9071,15 +9165,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5339 "reflect.h2" +#line 5405 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5344 "reflect.h2" +#line 5410 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5348 "reflect.h2" +#line 5414 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9100,7 +9194,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5374 "reflect.h2" +#line 5440 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9109,20 +9203,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5383 "reflect.h2" +#line 5449 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5389 "reflect.h2" +#line 5455 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5396 "reflect.h2" +#line 5462 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9137,16 +9231,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5426 "reflect.h2" +#line 5492 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5430 "reflect.h2" +#line 5496 "reflect.h2" } -#line 5436 "reflect.h2" +#line 5502 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9156,7 +9250,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5446 "reflect.h2" +#line 5512 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9164,17 +9258,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5453 "reflect.h2" +#line 5519 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5457 "reflect.h2" +#line 5523 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5464 "reflect.h2" +#line 5530 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9184,7 +9278,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5473 "reflect.h2" +#line 5539 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9192,24 +9286,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5480 "reflect.h2" +#line 5546 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5488 "reflect.h2" +#line 5554 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5492 "reflect.h2" +#line 5558 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5496 "reflect.h2" +#line 5562 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9221,22 +9315,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5507 "reflect.h2" +#line 5573 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5513 "reflect.h2" +#line 5579 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5517 "reflect.h2" +#line 5583 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5521 "reflect.h2" +#line 5587 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9244,7 +9338,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5528 "reflect.h2" +#line 5594 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9256,10 +9350,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5541 "reflect.h2" +#line 5607 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5544 "reflect.h2" +#line 5610 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9299,7 +9393,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5584 "reflect.h2" +#line 5650 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9311,14 +9405,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5595 "reflect.h2" +#line 5661 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5596 "reflect.h2" +#line 5662 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5597 "reflect.h2" +#line 5663 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5599 "reflect.h2" +#line 5665 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9328,10 +9422,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5608 "reflect.h2" +#line 5674 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5610 "reflect.h2" +#line 5676 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9353,14 +9447,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5631 "reflect.h2" +#line 5697 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5632 "reflect.h2" +#line 5698 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5633 "reflect.h2" +#line 5699 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5635 "reflect.h2" +#line 5701 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9374,7 +9468,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5648 "reflect.h2" +#line 5714 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9396,7 +9490,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5669 "reflect.h2" +#line 5735 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9407,12 +9501,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5679 "reflect.h2" +#line 5745 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5680 "reflect.h2" +#line 5746 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5685 "reflect.h2" +#line 5751 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9467,7 +9561,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5739 "reflect.h2" +#line 5805 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9507,7 +9601,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5778 "reflect.h2" +#line 5844 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9523,21 +9617,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5795 "reflect.h2" +#line 5861 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5796 "reflect.h2" +#line 5862 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5797 "reflect.h2" +#line 5863 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5799 "reflect.h2" +#line 5865 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5814 "reflect.h2" +#line 5880 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9545,7 +9639,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5821 "reflect.h2" +#line 5887 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9555,22 +9649,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5839 "reflect.h2" +#line 5905 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5844 "reflect.h2" +#line 5910 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5850 "reflect.h2" +#line 5916 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5856 "reflect.h2" +#line 5922 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9579,7 +9673,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5864 "reflect.h2" +#line 5930 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9591,7 +9685,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5875 "reflect.h2" +#line 5941 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9599,7 +9693,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5882 "reflect.h2" +#line 5948 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9620,7 +9714,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5903 "reflect.h2" +#line 5969 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9630,7 +9724,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5913 "reflect.h2" +#line 5979 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9653,33 +9747,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5937 "reflect.h2" +#line 6003 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5943 "reflect.h2" +#line 6009 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5947 "reflect.h2" +#line 6013 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5953 "reflect.h2" +#line 6019 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5961 "reflect.h2" +#line 6027 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9688,7 +9782,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 5969 "reflect.h2" +#line 6035 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9697,22 +9791,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 5979 "reflect.h2" +#line 6045 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 5983 "reflect.h2" +#line 6049 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 5987 "reflect.h2" +#line 6053 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 5991 "reflect.h2" +#line 6057 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9736,18 +9830,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6016 "reflect.h2" +#line 6082 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6031 "reflect.h2" +#line 6097 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6033 "reflect.h2" +#line 6099 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9758,15 +9852,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6048 "reflect.h2" +#line 6114 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6051 "reflect.h2" +#line 6117 "reflect.h2" } -#line 6053 "reflect.h2" +#line 6119 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9784,7 +9878,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6070 "reflect.h2" +#line 6136 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9792,7 +9886,7 @@ generation_function_context::generation_function_context(){} } } -#line 6077 "reflect.h2" +#line 6143 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9806,7 +9900,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6090 "reflect.h2" +#line 6156 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9822,14 +9916,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6111 "reflect.h2" +#line 6177 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6113 "reflect.h2" +#line 6179 "reflect.h2" } -#line 6115 "reflect.h2" +#line 6181 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9838,11 +9932,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6130 "reflect.h2" +#line 6196 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6132 "reflect.h2" +#line 6198 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9850,7 +9944,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6139 "reflect.h2" +#line 6205 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9859,37 +9953,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6147 "reflect.h2" +#line 6213 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6161 "reflect.h2" +#line 6227 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6165 "reflect.h2" +#line 6231 "reflect.h2" } -#line 6167 "reflect.h2" +#line 6233 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6171 "reflect.h2" +#line 6237 "reflect.h2" } -#line 6173 "reflect.h2" +#line 6239 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6177 "reflect.h2" +#line 6243 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9898,14 +9992,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6183 "reflect.h2" +#line 6249 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6188 "reflect.h2" +#line 6254 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9918,7 +10012,7 @@ size_t i{0}; } } -#line 6200 "reflect.h2" +#line 6266 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9940,7 +10034,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6221 "reflect.h2" +#line 6287 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -9959,7 +10053,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6239 "reflect.h2" +#line 6305 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -9975,14 +10069,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6254 "reflect.h2" +#line 6320 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6260 "reflect.h2" +#line 6326 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -9990,19 +10084,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6277 "reflect.h2" +#line 6343 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6278 "reflect.h2" +#line 6344 "reflect.h2" { -#line 6283 "reflect.h2" +#line 6349 "reflect.h2" } -#line 6286 "reflect.h2" +#line 6352 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10128,7 +10222,7 @@ size_t i{0}; ); } -#line 6411 "reflect.h2" +#line 6477 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10138,13 +10232,13 @@ size_t i{0}; ); } -#line 6420 "reflect.h2" +#line 6486 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6425 "reflect.h2" +#line 6491 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10155,12 +10249,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6437 "reflect.h2" +#line 6503 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6442 "reflect.h2" +#line 6508 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10194,7 +10288,7 @@ size_t i{0}; } -#line 6478 "reflect.h2" +#line 6544 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10203,19 +10297,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6501 "reflect.h2" +#line 6567 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6502 "reflect.h2" +#line 6568 "reflect.h2" { -#line 6507 "reflect.h2" +#line 6573 "reflect.h2" } -#line 6509 "reflect.h2" +#line 6575 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10317,19 +10411,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6610 "reflect.h2" +#line 6676 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6614 "reflect.h2" +#line 6680 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6638 "reflect.h2" +#line 6704 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10348,7 +10442,7 @@ size_t i{0}; return r; } -#line 6656 "reflect.h2" +#line 6722 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10363,7 +10457,7 @@ size_t i{0}; return r; } -#line 6670 "reflect.h2" +#line 6736 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10523,7 +10617,7 @@ size_t i{0}; } } -#line 6829 "reflect.h2" +#line 6895 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10532,7 +10626,7 @@ size_t i{0}; return r; } -#line 6837 "reflect.h2" +#line 6903 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10551,7 +10645,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6855 "reflect.h2" +#line 6921 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10583,7 +10677,7 @@ size_t i{0}; } } -#line 6886 "reflect.h2" +#line 6952 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10594,7 +10688,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6898 "reflect.h2" +#line 6964 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10633,7 +10727,7 @@ size_t i{0}; return r; } -#line 6939 "reflect.h2" +#line 7005 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10651,7 +10745,7 @@ size_t i{0}; }} } -#line 6959 "reflect.h2" +#line 7025 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10665,16 +10759,16 @@ size_t i{0}; } } -#line 6985 "reflect.h2" +#line 7051 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 6988 "reflect.h2" +#line 7054 "reflect.h2" } -#line 6990 "reflect.h2" +#line 7056 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10686,7 +10780,7 @@ size_t i{0}; } } -#line 7001 "reflect.h2" +#line 7067 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10694,14 +10788,14 @@ size_t i{0}; return r; } -#line 7008 "reflect.h2" +#line 7074 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7016 "reflect.h2" +#line 7082 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10727,7 +10821,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7044 "reflect.h2" +#line 7110 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10753,11 +10847,11 @@ size_t i{0}; return r; } -#line 7081 "reflect.h2" +#line 7147 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7083 "reflect.h2" +#line 7149 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10831,7 +10925,7 @@ size_t i{0}; return nullptr; } -#line 7156 "reflect.h2" +#line 7222 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10844,7 +10938,7 @@ size_t i{0}; }} } -#line 7168 "reflect.h2" +#line 7234 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10858,7 +10952,7 @@ size_t i{0}; }} } -#line 7181 "reflect.h2" +#line 7247 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10878,7 +10972,7 @@ size_t i{0}; return r; } -#line 7200 "reflect.h2" +#line 7266 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10889,7 +10983,7 @@ size_t i{0}; return r; } -#line 7210 "reflect.h2" +#line 7276 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10901,14 +10995,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7221 "reflect.h2" +#line 7287 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7233 "reflect.h2" +#line 7299 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10932,7 +11026,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7257 "reflect.h2" +#line 7323 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -10942,7 +11036,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7269 "reflect.h2" +#line 7335 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10958,7 +11052,7 @@ size_t i{0}; } } -#line 7289 "reflect.h2" +#line 7355 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10976,15 +11070,15 @@ size_t i{0}; }} } -#line 7325 "reflect.h2" +#line 7391 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7328 "reflect.h2" +#line 7394 "reflect.h2" } -#line 7330 "reflect.h2" +#line 7396 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11020,7 +11114,7 @@ size_t i{0}; return source; } -#line 7365 "reflect.h2" +#line 7431 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11036,7 +11130,7 @@ size_t i{0}; } } -#line 7381 "reflect.h2" +#line 7447 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11045,7 +11139,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11100,7 +11194,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7450 "reflect.h2" +#line 7516 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11222,7 +11316,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7572 "reflect.h2" +#line 7638 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 6aa3b7304..f52a448df 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3960,29 +3960,36 @@ sample_traverser: (idexpr: meta::id_expression, indent: i32) = autodiff_special_func: type = { public name : std::string; public n_args : int; - public has_return: bool; public is_member : bool; - public code : std::string; - public code_higher_order: std::string; + public code_primal : std::string; + public code_fwd : std::string; + public code_primal_higher_order: std::string; + public code_fwd_higher_order : std::string; - operator=: (out this, name_: std::string, n_args_: int, has_return_: bool, is_member_: bool, code_: std::string = "", code_higher_order_: std::string = "") = { - name = name_; - n_args = n_args_; - has_return = has_return_; - is_member = is_member_; - code = code_; - code_higher_order = code_higher_order_; + operator=: (out this, name_: std::string, n_args_: int, is_member_: bool, code_primal_: std::string = "", code_fwd_: std::string = "", + code_primal_higher_order_: std::string = "", code_fwd_higher_order_: std::string = "") = { + name = name_; + n_args = n_args_; + is_member = is_member_; - if code_higher_order.empty() { - code_higher_order = code; + code_primal = code_primal_; + code_fwd = code_fwd_; + code_primal_higher_order = code_primal_higher_order_; + code_fwd_higher_order = code_fwd_higher_order_; + + if code_primal_higher_order.empty() { + code_primal_higher_order = code_primal; + } + if code_fwd_higher_order.empty() { + code_fwd_higher_order = code_fwd; } } operator=: (out this, that) = {} // Default copy. is_match: (this, o: autodiff_special_func) -> bool = { - return name == o.name && n_args == o.n_args && has_return == o.has_return && is_member == o.is_member; + return name == o.name && n_args == o.n_args && is_member == o.is_member; } } @@ -4015,36 +4022,33 @@ autodiff_context: type = { // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. - // _r_ : name of the return value. - // _rd_ : name of derivative return value. // _a1_ : First argument value // _ad1_: First derivative argument value // _a2_ : Second argument value // _ad2_: Second derivative argument value public special_funcs : std::vector = ( - autodiff_special_func("sin", 1, /* has_return = */ true, /* is_member = */ false, - "_rd_ = cos(_a1_) * _ad1_;\n" - "_r_ = sin(_a1_);\n", - "_rd_ = _ad1_.sin(_a1_);\n" - "_r_ = sin(_a1_);\n", + autodiff_special_func("sin", 1, /* is_member = */ false, + "sin(_a1_)", + "cos(_a1_) * _ad1_", + "sin(_a1_)", + "_ad1_.sin(_a1_)", ), - autodiff_special_func("cos", 1, /* has_return = */ true, /* is_member = */ false, - "_rd_ = -sin(_a1_) * _ad1_;\n" - "_r_ = cos(_a1_);\n", - "_rd_ = _ad1_.cos(_a1_);\n" - "_r_ = cos(_a1_);\n", - + autodiff_special_func("cos", 1, /* is_member = */ false, + "cos(_a1_)", + "-sin(_a1_) * _ad1_", + "cos(_a1_)", + "_ad1_.cos(_a1_)", ), - autodiff_special_func("exp", 1, /* has_return = */ true, /* is_member = */ false, - "_rd_ = exp(_a1_) * _ad1_;\n" - "_r_ = exp(_a1_);\n", - "_rd_ = _ad1_.exp(_a1_);\n" - "_r_ = exp(_a1_);\n", + autodiff_special_func("exp", 1, /* is_member = */ false, + "exp(_a1_)", + "exp(_a1_) * _ad1_", + "exp(_a1_)", + "_ad1_.exp(_a1_)", ), - autodiff_special_func("push_back", 1, /* has_return = */ false, /* is_member = */ true, - "_o_.push_back(_a1_);\n" - "_od_.push_back(_ad1_);\n") + autodiff_special_func("push_back", 1, /* is_member = */ true, + "_o_.push_back(_a1_);", + "_od_.push_back(_ad1_);") ); public suffix: std::string = "_d"; @@ -4135,19 +4139,22 @@ autodiff_context: type = { } } - lookup_special_function_handling: (this, func_name: std::string, n_args: int, has_return: bool, is_member: bool) -> (m: bool, code: std::string) = { - lookup : autodiff_special_func = (func_name, n_args, has_return, is_member); + lookup_special_function_handling: (this, func_name: std::string, n_args: int, is_member: bool) -> (m: bool, code_primal: std::string, code_fwd: std::string) = { + lookup : autodiff_special_func = (func_name, n_args, is_member); m = false; - code = ""; + code_primal = ""; + code_fwd = ""; for special_funcs do (func) { if func.is_match(lookup) { m = true; if is_taylor() { - code = func.code_higher_order; + code_primal = func.code_primal_higher_order; + code_fwd = func.code_fwd_higher_order; } else { - code = func.code; + code_primal = func.code_primal; + code_fwd = func.code_fwd; } return; } @@ -4254,41 +4261,44 @@ autodiff_expression_handler: type = { base: type == simple_traverser; - public lhs: std::string; - public declare_p: std::string; - public declare_d: std::string; + public primal_expr: std::string = ""; + public fwd_expr : std::string = ""; - public primal_gen: bool = true; - - operator=: (out this, ctx_: *autodiff_context, lhs_: std::string, declare_p_: std::string = "", declare_d_: std::string = "") = { + operator=: (out this, ctx_: *autodiff_context) = { autodiff_handler_base = (ctx_); - lhs = lhs_; - declare_p = declare_p_; - declare_d = declare_d_; + } - if declare_d.empty() && !declare_p.empty() { - declare_d = declare_p; + add_suffix_if_not_wildcard: (this, lhs: std::string) -> std::string = { + if "_" == lhs { + return lhs; + } + else { + return lhs + ctx*.suffix; } } - gen_lhs_assignment: (inout this, prim: std::string, fwd: std::string, primal_first: bool = false) = { - lhs_d : std::string = lhs + ctx*.suffix; - if lhs == "_" { - // TODO: Maybe improve discard handling - lhs_d = lhs; - } + gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string) = { + diff += "(lhs_d)$ = (rhs_d)$;\n"; + diff += "(lhs)$ = (rhs)$;\n"; + } + gen_assignment: (inout this, lhs: std::string, lhs_d: std::string) + = gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); + gen_assignment: (inout this, lhs: std::string) + = gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); - fwd_str := "(lhs_d)$ (declare_d)$ = (fwd)$;\n"; - primal_str := "(lhs)$ (declare_p)$ = (prim)$;\n"; - if primal_gen && primal_first { - diff += primal_str; - } - diff += fwd_str; - if primal_gen && !primal_first { - diff += primal_str; - } + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string, type_d: std::string) = { + diff += "(lhs_d)$: (type_d)$ = (rhs_d)$;\n"; + diff += "(lhs)$ : (type)$ = (rhs)$;\n"; } + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string) + = gen_declaration(lhs, lhs_d, rhs, rhs_d, type, ctx*.get_ad_type(type)); + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, type: std::string) + = gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, ctx*.get_ad_type(type)); + gen_declaration: (inout this, lhs: std::string, type: std::string) + = gen_declaration(lhs, lhs + ctx*.suffix, primal_expr, fwd_expr, type, ctx*.get_ad_type(type)); + + handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { args : std::vector = (); @@ -4317,9 +4327,10 @@ autodiff_expression_handler: type = { return "error"; } - t := ctx*.gen_temporary(); - ad : autodiff_expression_handler = (ctx, t, ":"); // TODO: get type of expression + ad : autodiff_expression_handler = (ctx); ad..pre_traverse(bin_expr.get_terms().front().get_term()); + t := ctx*.gen_temporary(); + ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); return t; @@ -4328,9 +4339,10 @@ autodiff_expression_handler: type = { // Nothing special. A regular expression. expr := term; - t := ctx*.gen_temporary(); - ad : autodiff_expression_handler = (ctx, t, ":"); // TODO: get type of expression + ad : autodiff_expression_handler = (ctx); ad..pre_traverse(expr); + t := ctx*.gen_temporary(); + ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); return t; @@ -4399,11 +4411,7 @@ autodiff_expression_handler: type = { } } - r_arg := lhs; - if !has_return { - r_arg = ""; - } - if handle_special_function(object, object_d, function_name, args, r_arg) { + if handle_special_function(object, object_d, function_name, args) { return; } @@ -4451,7 +4459,9 @@ autodiff_expression_handler: type = { ret_name_d : std::string = ret_name + ctx*.suffix; - gen_lhs_assignment("(ret_temp)$.(ret_name)$", "(ret_temp)$.(ret_name_d)$", /* switch order = */ true); + primal_expr = "(ret_temp)$.(ret_name)$"; + fwd_expr = "(ret_temp)$.(ret_name_d)$"; + // TODO: check reverse order ctx*.add_for_differentiation(functions[0]); } @@ -4459,35 +4469,37 @@ autodiff_expression_handler: type = { // TODO: Add function to list of functions/objects for differentiation for the no return case. } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector, ret: std::string) -> bool = { + handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { - r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !ret.empty(), !object.empty()); + r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !object.empty()); if !r.m { return false; // No match } // Have a match, do the replacement - code: std::string = ""; - code = r.code; // TODO: Direct initialization gives error: no matching function for call to ‘std::__cxx11::basic_string::basic_string()’ + code_primal: std::string = r.code_primal; + code_fwd : std::string = r.code_fwd; if !object.empty() { - code = string_util::replace_all(code, "_o_", object); - code = string_util::replace_all(code, "_od_", object_d); - } + code_primal = string_util::replace_all(code_primal, "_o_", object); + code_primal = string_util::replace_all(code_primal, "_od_", object_d); - if !ret.empty() { - code = string_util::replace_all(code, "_r_", ret); - code = string_util::replace_all(code, "_rd_", ret + ctx*.suffix); + code_fwd = string_util::replace_all(code_fwd, "_o_", object); + code_fwd = string_util::replace_all(code_fwd, "_od_", object_d); } (copy i := 1) for args do (arg) { - code = string_util::replace_all(code, "_a(i)$_", arg); - code = string_util::replace_all(code, "_ad(i)$_", arg + ctx*.suffix); + code_primal = string_util::replace_all(code_primal, "_a(i)$_", arg); + code_primal = string_util::replace_all(code_primal, "_ad(i)$_", arg + ctx*.suffix); + + code_fwd = string_util::replace_all(code_fwd, "_a(i)$_", arg); + code_fwd = string_util::replace_all(code_fwd, "_ad(i)$_", arg + ctx*.suffix); } - diff += code; + primal_expr = code_primal; + fwd_expr = code_fwd; return true; } @@ -4557,7 +4569,8 @@ autodiff_expression_handler: type = { first = false; } - gen_lhs_assignment(primal, fwd); + primal_expr = primal; + fwd_expr = fwd; } traverse: (override inout this, binexpr: meta::multiplicative_expression) = { @@ -4600,18 +4613,14 @@ autodiff_expression_handler: type = { if i + 1 == terms.ssize() { - // Last item - gen_lhs_assignment(primal, fwd); + primal_expr = primal; + fwd_expr = fwd; } else { // Temporary t := ctx*.gen_temporary(); t_d := t + ctx*.suffix; - // TODO: Get type of expression, in order to define the type of t. - diff += "(t_d)$ := (fwd)$;"; - if primal_gen { - diff += "(t)$ := (primal)$;"; - } + gen_declaration(t, t_d, primal, fwd, "", ""); arg_a = t; arg_a_d = t_d; @@ -4663,33 +4672,29 @@ autodiff_expression_handler: type = { obj_access += term.get_op() + term.get_id_expression().to_string(); } - gen_lhs_assignment("(obj_name)$(obj_access)$", "(obj_name_d)$(obj_access)$"); + primal_expr = "(obj_name)$(obj_access)$"; + fwd_expr = "(obj_name_d)$(obj_access)$"; } } traverse: (override inout this, primary: meta::primary_expression) = { if primary.is_identifier() { - gen_lhs_assignment(primary.to_string(), primary.to_string() + ctx*.suffix); + primal_expr = primary.to_string(); + fwd_expr = primary.to_string() + ctx*.suffix; } else if primary.is_expression_list() { if primary.as_expression_list().is_empty() { - gen_lhs_assignment("()", "()"); + primal_expr = "()"; + fwd_expr = "()"; } else { primary.error("AD: Do not know how to handle non empty expression list inside of primary_expression: (primary.to_string())$"); } } else if primary.is_literal() { - literal_str := primary.to_string(); - - ad_init : std::string = "()"; - - // TODO: Determine propre zero initializer from type of literal. - if declare_d == ":" || declare_d == ": _" { - ad_init = ctx*.get_ad_type("double") + "()"; - } - gen_lhs_assignment(primary.to_string(), ad_init); + primal_expr = primary.to_string(); + fwd_expr = "()"; } else if primary.is_declaration() { primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); @@ -4729,15 +4734,24 @@ autodiff_stmt_handler: type = { ad_type : = ctx*.get_ad_type(type); + prim_init: std::string = ""; + fwd_init : std::string = ""; + if o.has_initializer() { - ad: autodiff_expression_handler = (ctx, lhs, ": " + type, ": " + ad_type); + ad: autodiff_expression_handler = (ctx); ad.pre_traverse(o.get_initializer()); append(ad); + + prim_init = " = " + ad.primal_expr; + fwd_init = " = " + ad.fwd_expr; + + if type == "_" && ad.fwd_expr == "()" { + // Special handling for auto initialization from a literal. + fwd_init = " = " + ctx*.get_ad_type("double") + "()"; + } } - else { - diff += "(lhs)$(ctx*.suffix)$ : (ad_type)$;\n"; - diff += "(lhs)$ : (type)$;\n"; - } + diff += "(lhs)$(ctx*.suffix)$ : (ad_type)$(fwd_init)$;\n"; + diff += "(lhs)$ : (type)$(prim_init)$;\n"; } @@ -4770,8 +4784,9 @@ autodiff_stmt_handler: type = { // TODO: Remove assumptions // - Return expression is always active. (Look this up in mf or so.) // - Return was converted to a two parameter return with the name r. - ad: autodiff_expression_handler = (ctx, "r"); + ad: autodiff_expression_handler = (ctx); ad..pre_traverse(stmt.get_expression()); + ad.gen_assignment("r",); append(ad); } else { @@ -4856,9 +4871,9 @@ autodiff_stmt_handler: type = { // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each // @ is one of a list of operators at the same grammar precedence - h: autodiff_expression_handler = (ctx, lhs.to_string()); + h: autodiff_expression_handler = (ctx); h.pre_traverse(assignment_terms[1].get_term()); - + h.gen_assignment(lhs.to_string()); append(h); } else { @@ -4949,8 +4964,10 @@ autodiff_stmt_handler: type = { return; } - ad: autodiff_expression_handler = (ctx, ""); + ad: autodiff_expression_handler = (ctx); ad.handle_function_call(postfix, false); + ad.diff += ad.fwd_expr + "\n"; + ad.diff += ad.primal_expr + "\n"; append(ad); } @@ -5048,18 +5065,18 @@ autodiff_declaration_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { ad_name : std::string = "(o.name())$(ctx*.suffix)$"; ad_type : std::string = ctx*.get_ad_type(o.type()); - + ad_init : std::string = ""; if o.has_initializer() { - ad: autodiff_expression_handler = (ctx, "(o.name())$", ": " + o.type(), ": " + ad_type); - ad.primal_gen = false; + ad: autodiff_expression_handler = (ctx); ad.pre_traverse(o.get_initializer()); - append(ad); - } - else { - diff = "(ad_name)$ : (ad_type)$;"; + + assert(ad.diff.empty()); + ad_init = " = " +ad.fwd_expr; } + diff = "(ad_name)$ : (ad_type)$(ad_init)$;"; + if is_type_context { diff_ad_type += "public (diff)$\n"; From a286c841569e7043210ee1fb4bcfee0f175fdf72 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 10:48:47 +0200 Subject: [PATCH 33/54] Handling of member access. --- regression-tests/pure2-autodiff.cpp2 | 12 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 237 +++-- .../test-results/pure2-autodiff.cpp2.output | 32 + source/reflect.h | 884 +++++++++--------- source/reflect.h2 | 8 +- 6 files changed, 637 insertions(+), 537 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 300c4591b..515a2aee1 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -4,6 +4,10 @@ func_outer: (x: double, y: double) -> (ret: double) = { ret = x + y; } +type_outer: type = { + public a: double = 0.0; +} + ad_test: @autodiff @print type = { add_1: (x: double, y: double) -> (r: double) = { @@ -159,6 +163,13 @@ ad_test: @autodiff @print type = { r = r + t; } } + + type_outer_use: (x: double, y: double) -> (r: double) = { + t : type_outer = (); + t.a = x; + + r = t.a + y; + } } } @@ -205,6 +216,7 @@ main: () = { write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index cdd65c3e1..29dd754ff 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -24,4 +24,5 @@ diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index cbda55f01..453376fa1 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -10,9 +10,13 @@ namespace ad_name { #line 7 "pure2-autodiff.cpp2" +class type_outer; + + +#line 11 "pure2-autodiff.cpp2" class ad_test; -#line 163 "pure2-autodiff.cpp2" +#line 174 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -27,147 +31,162 @@ using func_outer_ret = double; #line 3 "pure2-autodiff.cpp2" [[nodiscard]] auto func_outer(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_ret; + +#line 7 "pure2-autodiff.cpp2" +class type_outer { + public: double a {0.0}; + public: type_outer() = default; + public: type_outer(type_outer const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(type_outer const&) -> void = delete; + +#line 9 "pure2-autodiff.cpp2" +}; + struct func_outer_d_ret { double ret; double ret_d; }; [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret; - -#line 7 "pure2-autodiff.cpp2" +#line 11 "pure2-autodiff.cpp2" class ad_test { using add_1_ret = double; -#line 9 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 61 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 69 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 73 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 81 "pure2-autodiff.cpp2" +#line 85 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 90 "pure2-autodiff.cpp2" +#line 94 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 94 "pure2-autodiff.cpp2" +#line 98 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 100 "pure2-autodiff.cpp2" +#line 104 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 108 "pure2-autodiff.cpp2" +#line 112 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 115 "pure2-autodiff.cpp2" +#line 119 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 122 "pure2-autodiff.cpp2" +#line 126 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 129 "pure2-autodiff.cpp2" +#line 133 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 138 "pure2-autodiff.cpp2" +#line 142 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 149 "pure2-autodiff.cpp2" +#line 153 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; +using type_outer_use_ret = double; + + +#line 167 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; struct add_1_d_ret { double r; double r_d; }; @@ -277,19 +296,23 @@ struct for_loop_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_d_ret; +struct type_outer_use_d_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto type_outer_use_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_use_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 162 "pure2-autodiff.cpp2" +#line 173 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 166 "pure2-autodiff.cpp2" +#line 177 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -309,12 +332,12 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 169 "pure2-autodiff.cpp2" +#line 180 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 175 "pure2-autodiff.cpp2" +#line 186 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -336,122 +359,122 @@ ret = x + y; return { std::move(ret), std::move(ret_d) }; } -#line 9 "pure2-autodiff.cpp2" +#line 13 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 10 "pure2-autodiff.cpp2" +#line 14 "pure2-autodiff.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 14 "pure2-autodiff.cpp2" +#line 18 "pure2-autodiff.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 18 "pure2-autodiff.cpp2" +#line 22 "pure2-autodiff.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 22 "pure2-autodiff.cpp2" +#line 26 "pure2-autodiff.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 26 "pure2-autodiff.cpp2" +#line 30 "pure2-autodiff.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 30 "pure2-autodiff.cpp2" +#line 34 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 34 "pure2-autodiff.cpp2" +#line 38 "pure2-autodiff.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 38 "pure2-autodiff.cpp2" +#line 42 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 42 "pure2-autodiff.cpp2" +#line 46 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 46 "pure2-autodiff.cpp2" +#line 50 "pure2-autodiff.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 50 "pure2-autodiff.cpp2" +#line 54 "pure2-autodiff.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 54 "pure2-autodiff.cpp2" +#line 58 "pure2-autodiff.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 58 "pure2-autodiff.cpp2" +#line 62 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 61 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 62 "pure2-autodiff.cpp2" +#line 66 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 66 "pure2-autodiff.cpp2" +#line 70 "pure2-autodiff.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } -#line 69 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 70 "pure2-autodiff.cpp2" +#line 74 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 73 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 74 "pure2-autodiff.cpp2" +#line 78 "pure2-autodiff.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -459,10 +482,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 81 "pure2-autodiff.cpp2" +#line 85 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 82 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -471,24 +494,24 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 90 "pure2-autodiff.cpp2" +#line 94 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 94 "pure2-autodiff.cpp2" +#line 98 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 95 "pure2-autodiff.cpp2" +#line 99 "pure2-autodiff.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 100 "pure2-autodiff.cpp2" +#line 104 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 101 "pure2-autodiff.cpp2" +#line 105 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -496,40 +519,40 @@ return { std::move(ret), std::move(ret_d) }; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 108 "pure2-autodiff.cpp2" +#line 112 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 109 "pure2-autodiff.cpp2" +#line 113 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 115 "pure2-autodiff.cpp2" +#line 119 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 116 "pure2-autodiff.cpp2" +#line 120 "pure2-autodiff.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 122 "pure2-autodiff.cpp2" +#line 126 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 123 "pure2-autodiff.cpp2" +#line 127 "pure2-autodiff.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 129 "pure2-autodiff.cpp2" +#line 133 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 130 "pure2-autodiff.cpp2" +#line 134 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -538,10 +561,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 138 "pure2-autodiff.cpp2" +#line 142 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 139 "pure2-autodiff.cpp2" +#line 143 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -552,10 +575,10 @@ return { std::move(ret), std::move(ret_d) }; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 149 "pure2-autodiff.cpp2" +#line 153 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 150 "pure2-autodiff.cpp2" +#line 154 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -569,6 +592,16 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } +#line 167 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ + cpp2::impl::deferred_init r; +#line 168 "pure2-autodiff.cpp2" + type_outer t {}; + t.a = x; + + r.construct(cpp2::move(t).a + y); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_d_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d; @@ -877,13 +910,30 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 163 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::type_outer_use_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_use_d_ret{ + double r {0.0}; + double r_d {0.0}; +type_outer t_d {}; + + type_outer t {}; + t_d.a = x_d; + t.a = x; + + double temp_1_d {cpp2::move(t_d).a}; + + double temp_1 {cpp2::move(t).a}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + +#line 174 "pure2-autodiff.cpp2" } -#line 166 "pure2-autodiff.cpp2" +#line 177 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 167 "pure2-autodiff.cpp2" +#line 178 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -920,12 +970,12 @@ double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 171 "pure2-autodiff.cpp2" +#line 182 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 175 "pure2-autodiff.cpp2" +#line 186 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -958,7 +1008,8 @@ auto main() -> int{ write_output("intermediate no init", x, x_d, y, y_d, ad_name::ad_test::intermediate_no_init_d(x, x_d, y, y_d)); write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); + write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); auto r_twice {ad_test_twice::mul_1_d_d2(x, x_d, cpp2::move(x_d), 0.0)}; std::cout << "2nd order diff of x*x at " + cpp2::to_string(cpp2::move(x)) + " = " + cpp2::to_string(cpp2::move(r_twice).r_d_d2) + "" << std::endl; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 9095539ab..adcccd359 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -286,6 +286,17 @@ ad_test:/* @autodiff @print */ type = return; } + type_outer_use:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: type_outer = (); + t.a = x; + r = t.a + y; + return; + } + add_1_d:( in x: double, in x_d: double, @@ -778,6 +789,27 @@ ad_test:/* @autodiff @print */ type = } return; } + + type_outer_use_d:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + t_d: type_outer = (); + t: type_outer = (); + t_d.a = x_d; + t.a = x; + temp_1_d: double = t_d.a; + temp_1: double = t.a; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } } diff --git a/source/reflect.h b/source/reflect.h index d9758feb0..2fc1fff80 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -129,80 +129,80 @@ class autodiff_expression_handler; #line 4708 "reflect.h2" class autodiff_stmt_handler; -#line 4980 "reflect.h2" +#line 4982 "reflect.h2" class autodiff_declaration_handler; -#line 5216 "reflect.h2" +#line 5218 "reflect.h2" class expression_flags; -#line 5232 "reflect.h2" +#line 5234 "reflect.h2" class regex_token; -#line 5259 "reflect.h2" +#line 5261 "reflect.h2" class regex_token_check; -#line 5280 "reflect.h2" +#line 5282 "reflect.h2" class regex_token_code; -#line 5301 "reflect.h2" +#line 5303 "reflect.h2" class regex_token_empty; -#line 5319 "reflect.h2" +#line 5321 "reflect.h2" class regex_token_list; -#line 5371 "reflect.h2" +#line 5373 "reflect.h2" class parse_context_group_state; -#line 5432 "reflect.h2" +#line 5434 "reflect.h2" class parse_context_branch_reset_state; -#line 5475 "reflect.h2" +#line 5477 "reflect.h2" class parse_context; -#line 5876 "reflect.h2" +#line 5878 "reflect.h2" class generation_function_context; -#line 5894 "reflect.h2" +#line 5896 "reflect.h2" class generation_context; -#line 6093 "reflect.h2" +#line 6095 "reflect.h2" class alternative_token; -#line 6108 "reflect.h2" +#line 6110 "reflect.h2" class alternative_token_gen; -#line 6173 "reflect.h2" +#line 6175 "reflect.h2" class any_token; -#line 6190 "reflect.h2" +#line 6192 "reflect.h2" class atomic_group_token; -#line 6220 "reflect.h2" +#line 6222 "reflect.h2" class char_token; -#line 6335 "reflect.h2" +#line 6337 "reflect.h2" class class_token; -#line 6559 "reflect.h2" +#line 6561 "reflect.h2" class group_ref_token; -#line 6696 "reflect.h2" +#line 6698 "reflect.h2" class group_token; -#line 7043 "reflect.h2" +#line 7045 "reflect.h2" class lookahead_lookbehind_token; -#line 7138 "reflect.h2" +#line 7140 "reflect.h2" class range_token; -#line 7295 "reflect.h2" +#line 7297 "reflect.h2" class special_range_token; -#line 7381 "reflect.h2" +#line 7383 "reflect.h2" template class regex_generator; -#line 7638 "reflect.h2" +#line 7640 "reflect.h2" } } @@ -1953,63 +1953,63 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba #line 4856 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4884 "reflect.h2" +#line 4886 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4889 "reflect.h2" +#line 4891 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4893 "reflect.h2" +#line 4895 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4897 "reflect.h2" +#line 4899 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4901 "reflect.h2" +#line 4903 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4905 "reflect.h2" +#line 4907 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4909 "reflect.h2" +#line 4911 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4913 "reflect.h2" +#line 4915 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4917 "reflect.h2" +#line 4919 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4921 "reflect.h2" +#line 4923 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4925 "reflect.h2" +#line 4927 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4929 "reflect.h2" +#line 4931 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4933 "reflect.h2" +#line 4935 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4937 "reflect.h2" +#line 4939 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4942 "reflect.h2" +#line 4944 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4974 "reflect.h2" +#line 4976 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4978 "reflect.h2" +#line 4980 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4984 "reflect.h2" +#line 4986 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2019,37 +2019,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4996 "reflect.h2" +#line 4998 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5001 "reflect.h2" +#line 5003 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5065 "reflect.h2" +#line 5067 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5091 "reflect.h2" +#line 5093 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5113 "reflect.h2" +#line 5115 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5118 "reflect.h2" +#line 5120 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5121 "reflect.h2" +#line 5123 "reflect.h2" }; -#line 5124 "reflect.h2" +#line 5126 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5212 "reflect.h2" +#line 5214 "reflect.h2" using error_func = std::function x)>; -#line 5216 "reflect.h2" +#line 5218 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2084,20 +2084,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5224 "reflect.h2" +#line 5226 "reflect.h2" }; -#line 5232 "reflect.h2" +#line 5234 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5240 "reflect.h2" +#line 5242 "reflect.h2" public: explicit regex_token(); -#line 5245 "reflect.h2" +#line 5247 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2109,103 +2109,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5251 "reflect.h2" +#line 5253 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5257 "reflect.h2" +#line 5259 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5263 "reflect.h2" +#line 5265 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5270 "reflect.h2" +#line 5272 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5274 "reflect.h2" +#line 5276 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5275 "reflect.h2" +#line 5277 "reflect.h2" }; -#line 5278 "reflect.h2" +#line 5280 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5284 "reflect.h2" +#line 5286 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5291 "reflect.h2" +#line 5293 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5295 "reflect.h2" +#line 5297 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5296 "reflect.h2" +#line 5298 "reflect.h2" }; -#line 5299 "reflect.h2" +#line 5301 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5305 "reflect.h2" +#line 5307 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5309 "reflect.h2" +#line 5311 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5313 "reflect.h2" +#line 5315 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5314 "reflect.h2" +#line 5316 "reflect.h2" }; -#line 5317 "reflect.h2" +#line 5319 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5323 "reflect.h2" +#line 5325 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5330 "reflect.h2" +#line 5332 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5336 "reflect.h2" +#line 5338 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5342 "reflect.h2" +#line 5344 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5350 "reflect.h2" +#line 5352 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2213,10 +2213,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5362 "reflect.h2" +#line 5364 "reflect.h2" }; -#line 5365 "reflect.h2" +#line 5367 "reflect.h2" // // Parse and generation context. // @@ -2232,33 +2232,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5385 "reflect.h2" +#line 5387 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5392 "reflect.h2" +#line 5394 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5404 "reflect.h2" +#line 5406 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5409 "reflect.h2" +#line 5411 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5413 "reflect.h2" +#line 5415 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5427 "reflect.h2" +#line 5429 "reflect.h2" }; -#line 5430 "reflect.h2" +#line 5432 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2271,25 +2271,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5448 "reflect.h2" +#line 5450 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5454 "reflect.h2" +#line 5456 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5461 "reflect.h2" +#line 5463 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5468 "reflect.h2" +#line 5470 "reflect.h2" }; -#line 5471 "reflect.h2" +#line 5473 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2305,7 +2305,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5487 "reflect.h2" +#line 5489 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2313,64 +2313,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5498 "reflect.h2" +#line 5500 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5511 "reflect.h2" +#line 5513 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5519 "reflect.h2" +#line 5521 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5523 "reflect.h2" +#line 5525 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5527 "reflect.h2" +#line 5529 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5539 "reflect.h2" +#line 5541 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5546 "reflect.h2" +#line 5548 "reflect.h2" public: auto next_alternative() & -> void; -#line 5552 "reflect.h2" +#line 5554 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5558 "reflect.h2" +#line 5560 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5562 "reflect.h2" +#line 5564 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5573 "reflect.h2" +#line 5575 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5577 "reflect.h2" +#line 5579 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5583 "reflect.h2" +#line 5585 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5587 "reflect.h2" +#line 5589 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5594 "reflect.h2" +#line 5596 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5605 "reflect.h2" +#line 5607 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2378,51 +2378,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5649 "reflect.h2" +#line 5651 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5661 "reflect.h2" +#line 5663 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5674 "reflect.h2" +#line 5676 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5697 "reflect.h2" +#line 5699 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5714 "reflect.h2" +#line 5716 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5735 "reflect.h2" +#line 5737 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5745 "reflect.h2" +#line 5747 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5749 "reflect.h2" +#line 5751 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5805 "reflect.h2" +#line 5807 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5844 "reflect.h2" +#line 5846 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5859 "reflect.h2" +#line 5861 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2434,10 +2434,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5870 "reflect.h2" +#line 5872 "reflect.h2" }; -#line 5873 "reflect.h2" +#line 5875 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2447,16 +2447,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5887 "reflect.h2" +#line 5889 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5890 "reflect.h2" +#line 5892 "reflect.h2" }; -#line 5893 "reflect.h2" +#line 5895 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2476,68 +2476,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5915 "reflect.h2" +#line 5917 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5921 "reflect.h2" +#line 5923 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5930 "reflect.h2" +#line 5932 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5941 "reflect.h2" +#line 5943 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5948 "reflect.h2" +#line 5950 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5968 "reflect.h2" +#line 5970 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5978 "reflect.h2" +#line 5980 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6001 "reflect.h2" +#line 6003 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6009 "reflect.h2" +#line 6011 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6013 "reflect.h2" +#line 6015 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6019 "reflect.h2" +#line 6021 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6025 "reflect.h2" +#line 6027 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6035 "reflect.h2" +#line 6037 "reflect.h2" public: auto finish_context() & -> void; -#line 6043 "reflect.h2" +#line 6045 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6049 "reflect.h2" +#line 6051 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6053 "reflect.h2" +#line 6055 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6057 "reflect.h2" +#line 6059 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6081 "reflect.h2" +#line 6083 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2545,7 +2545,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6087 "reflect.h2" +#line 6089 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2565,27 +2565,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6106 "reflect.h2" +#line 6108 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6112 "reflect.h2" +#line 6114 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6119 "reflect.h2" +#line 6121 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6136 "reflect.h2" +#line 6138 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6143 "reflect.h2" +#line 6145 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6156 "reflect.h2" +#line 6158 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2593,19 +2593,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6168 "reflect.h2" +#line 6170 "reflect.h2" }; -#line 6171 "reflect.h2" +#line 6173 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6177 "reflect.h2" +#line 6179 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6181 "reflect.h2" +#line 6183 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2613,7 +2613,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6186 "reflect.h2" +#line 6188 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2621,17 +2621,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6194 "reflect.h2" +#line 6196 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6205 "reflect.h2" +#line 6207 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6213 "reflect.h2" +#line 6215 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2639,7 +2639,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6216 "reflect.h2" +#line 6218 "reflect.h2" }; // Regex syntax: a @@ -2647,34 +2647,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6224 "reflect.h2" +#line 6226 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6233 "reflect.h2" +#line 6235 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6239 "reflect.h2" +#line 6241 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6243 "reflect.h2" +#line 6245 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6266 "reflect.h2" +#line 6268 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6287 "reflect.h2" +#line 6289 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6305 "reflect.h2" +#line 6307 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6320 "reflect.h2" +#line 6322 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6326 "reflect.h2" +#line 6328 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2682,33 +2682,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6330 "reflect.h2" +#line 6332 "reflect.h2" }; -#line 6333 "reflect.h2" +#line 6335 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6339 "reflect.h2" +#line 6341 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6351 "reflect.h2" +#line 6353 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6477 "reflect.h2" +#line 6479 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6486 "reflect.h2" +#line 6488 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6491 "reflect.h2" +#line 6493 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2716,20 +2716,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6498 "reflect.h2" +#line 6500 "reflect.h2" }; -#line 6501 "reflect.h2" +#line 6503 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6542 "reflect.h2" +#line 6544 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6553 "reflect.h2" +#line 6555 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2739,20 +2739,20 @@ class class_token class group_ref_token : public regex_token { -#line 6563 "reflect.h2" +#line 6565 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6575 "reflect.h2" +#line 6577 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6676 "reflect.h2" +#line 6678 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6680 "reflect.h2" +#line 6682 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2760,10 +2760,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6683 "reflect.h2" +#line 6685 "reflect.h2" }; -#line 6686 "reflect.h2" +#line 6688 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2777,29 +2777,29 @@ class group_ref_token class group_token : public regex_token { -#line 6700 "reflect.h2" +#line 6702 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6722 "reflect.h2" +#line 6724 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6736 "reflect.h2" +#line 6738 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6895 "reflect.h2" +#line 6897 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6903 "reflect.h2" +#line 6905 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6921 "reflect.h2" +#line 6923 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6952 "reflect.h2" +#line 6954 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2808,25 +2808,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6959 "reflect.h2" +#line 6961 "reflect.h2" }; -#line 6962 "reflect.h2" +#line 6964 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7003 "reflect.h2" +#line 7005 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7023 "reflect.h2" +#line 7025 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7039 "reflect.h2" +#line 7041 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2834,20 +2834,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7047 "reflect.h2" +#line 7049 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7056 "reflect.h2" +#line 7058 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7067 "reflect.h2" +#line 7069 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7074 "reflect.h2" +#line 7076 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2855,26 +2855,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7077 "reflect.h2" +#line 7079 "reflect.h2" }; -#line 7080 "reflect.h2" +#line 7082 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7108 "reflect.h2" +#line 7110 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7136 "reflect.h2" +#line 7138 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7142 "reflect.h2" +#line 7144 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2884,22 +2884,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7222 "reflect.h2" +#line 7224 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7234 "reflect.h2" +#line 7236 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7247 "reflect.h2" +#line 7249 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7266 "reflect.h2" +#line 7268 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7276 "reflect.h2" +#line 7278 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7287 "reflect.h2" +#line 7289 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2907,16 +2907,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7290 "reflect.h2" +#line 7292 "reflect.h2" }; -#line 7293 "reflect.h2" +#line 7295 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7299 "reflect.h2" +#line 7301 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2925,7 +2925,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7329 "reflect.h2" +#line 7331 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2934,14 +2934,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7351 "reflect.h2" +#line 7353 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7373 "reflect.h2" +#line 7375 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2962,24 +2962,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7396 "reflect.h2" +#line 7398 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7431 "reflect.h2" +#line 7433 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7445 "reflect.h2" +#line 7447 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7457 "reflect.h2" +#line 7459 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7512 "reflect.h2" +#line 7514 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2990,7 +2990,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7638 "reflect.h2" +#line 7640 "reflect.h2" } } @@ -8363,7 +8363,7 @@ auto i{0}; { if (CPP2_UFCS(is_identifier)(primary)) { primal_expr = CPP2_UFCS(to_string)(primary); - fwd_expr = CPP2_UFCS(to_string)(primary) + (*cpp2::impl::assert_not_null(ctx)).suffix; + fwd_expr = add_suffix_if_not_wildcard(primal_expr); } else {if (CPP2_UFCS(is_expression_list)(primary)) { if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { @@ -8537,7 +8537,9 @@ auto i{0}; { // If this is not an assignment to a parameter or return object, skip it auto lhs_rhs {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)(expr)}; - auto lhs {CPP2_UFCS(get_first_token_ignoring_this)(cpp2::move(lhs_rhs).lhs)}; + + autodiff_expression_handler h_lhs {ctx}; + CPP2_UFCS(pre_traverse)(h_lhs, cpp2::move(lhs_rhs).lhs); auto assignment {CPP2_UFCS(as_assignment_expression)(expr)}; @@ -8552,7 +8554,7 @@ auto i{0}; autodiff_expression_handler h {ctx}; CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, CPP2_UFCS(to_string)(cpp2::move(lhs))); + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, cpp2::move(h_lhs).fwd_expr); append(cpp2::move(h)); } else { @@ -8560,79 +8562,79 @@ auto i{0}; } } -#line 4884 "reflect.h2" +#line 4886 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ // TDOO: Move meta::expression logic here CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); } -#line 4889 "reflect.h2" +#line 4891 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4893 "reflect.h2" +#line 4895 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4897 "reflect.h2" +#line 4899 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4901 "reflect.h2" +#line 4903 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4905 "reflect.h2" +#line 4907 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4909 "reflect.h2" +#line 4911 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4913 "reflect.h2" +#line 4915 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4917 "reflect.h2" +#line 4919 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4921 "reflect.h2" +#line 4923 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4925 "reflect.h2" +#line 4927 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4929 "reflect.h2" +#line 4931 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4933 "reflect.h2" +#line 4935 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4937 "reflect.h2" +#line 4939 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4942 "reflect.h2" +#line 4944 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8641,7 +8643,7 @@ auto i{0}; { auto i{0}; -#line 4949 "reflect.h2" +#line 4951 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8656,7 +8658,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4962 "reflect.h2" +#line 4964 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8669,27 +8671,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4974 "reflect.h2" +#line 4976 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4991 "reflect.h2" +#line 4993 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4994 "reflect.h2" +#line 4996 "reflect.h2" } -#line 4996 "reflect.h2" +#line 4998 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5001 "reflect.h2" +#line 5003 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8733,10 +8735,10 @@ auto i{0}; return ; } -#line 5045 "reflect.h2" +#line 5047 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5048 "reflect.h2" +#line 5050 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8753,7 +8755,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5065 "reflect.h2" +#line 5067 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -8779,7 +8781,7 @@ auto i{0}; diff = ""; } -#line 5091 "reflect.h2" +#line 5093 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -8801,17 +8803,17 @@ auto i{0}; } } -#line 5113 "reflect.h2" +#line 5115 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5118 "reflect.h2" +#line 5120 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5124 "reflect.h2" +#line 5126 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8847,7 +8849,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5160 "reflect.h2" +#line 5162 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8976,7 +8978,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5198 "reflect.h2" +#line 5200 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8992,11 +8994,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5214 "reflect.h2" +#line 5216 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5218 "reflect.h2" +#line 5220 "reflect.h2" // mod: i // mod: m // mod: s @@ -9004,116 +9006,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5227 "reflect.h2" +#line 5229 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5236 "reflect.h2" +#line 5238 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5238 "reflect.h2" +#line 5240 "reflect.h2" } -#line 5240 "reflect.h2" +#line 5242 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5242 "reflect.h2" +#line 5244 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5248 "reflect.h2" +#line 5250 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5249 "reflect.h2" +#line 5251 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5250 "reflect.h2" +#line 5252 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5265 "reflect.h2" +#line 5267 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5268 "reflect.h2" +#line 5270 "reflect.h2" } -#line 5270 "reflect.h2" +#line 5272 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5274 "reflect.h2" +#line 5276 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5286 "reflect.h2" +#line 5288 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5289 "reflect.h2" +#line 5291 "reflect.h2" } -#line 5291 "reflect.h2" +#line 5293 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5295 "reflect.h2" +#line 5297 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5305 "reflect.h2" +#line 5307 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5307 "reflect.h2" +#line 5309 "reflect.h2" } -#line 5309 "reflect.h2" +#line 5311 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5313 "reflect.h2" +#line 5315 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5325 "reflect.h2" +#line 5327 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5328 "reflect.h2" +#line 5330 "reflect.h2" } -#line 5330 "reflect.h2" +#line 5332 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5336 "reflect.h2" +#line 5338 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5342 "reflect.h2" +#line 5344 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9122,7 +9124,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5350 "reflect.h2" +#line 5352 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9138,7 +9140,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5378 "reflect.h2" +#line 5380 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9146,14 +9148,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5386 "reflect.h2" +#line 5388 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5393 "reflect.h2" +#line 5395 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9165,15 +9167,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5405 "reflect.h2" +#line 5407 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5410 "reflect.h2" +#line 5412 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5414 "reflect.h2" +#line 5416 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9194,7 +9196,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5440 "reflect.h2" +#line 5442 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9203,20 +9205,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5449 "reflect.h2" +#line 5451 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5455 "reflect.h2" +#line 5457 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5462 "reflect.h2" +#line 5464 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9231,16 +9233,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5492 "reflect.h2" +#line 5494 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5496 "reflect.h2" +#line 5498 "reflect.h2" } -#line 5502 "reflect.h2" +#line 5504 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9250,7 +9252,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5512 "reflect.h2" +#line 5514 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9258,17 +9260,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5519 "reflect.h2" +#line 5521 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5523 "reflect.h2" +#line 5525 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5530 "reflect.h2" +#line 5532 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9278,7 +9280,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5539 "reflect.h2" +#line 5541 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9286,24 +9288,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5546 "reflect.h2" +#line 5548 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5554 "reflect.h2" +#line 5556 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5558 "reflect.h2" +#line 5560 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5562 "reflect.h2" +#line 5564 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9315,22 +9317,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5573 "reflect.h2" +#line 5575 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5579 "reflect.h2" +#line 5581 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5583 "reflect.h2" +#line 5585 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5587 "reflect.h2" +#line 5589 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9338,7 +9340,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5594 "reflect.h2" +#line 5596 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9350,10 +9352,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5607 "reflect.h2" +#line 5609 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5610 "reflect.h2" +#line 5612 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9393,7 +9395,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5650 "reflect.h2" +#line 5652 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9405,14 +9407,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5661 "reflect.h2" +#line 5663 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5662 "reflect.h2" +#line 5664 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5663 "reflect.h2" +#line 5665 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5665 "reflect.h2" +#line 5667 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9422,10 +9424,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5674 "reflect.h2" +#line 5676 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5676 "reflect.h2" +#line 5678 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9447,14 +9449,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5697 "reflect.h2" +#line 5699 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5698 "reflect.h2" +#line 5700 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5699 "reflect.h2" +#line 5701 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5701 "reflect.h2" +#line 5703 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9468,7 +9470,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5714 "reflect.h2" +#line 5716 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9490,7 +9492,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5735 "reflect.h2" +#line 5737 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9501,12 +9503,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5745 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5746 "reflect.h2" +#line 5748 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5751 "reflect.h2" +#line 5753 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9561,7 +9563,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5805 "reflect.h2" +#line 5807 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9601,7 +9603,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5844 "reflect.h2" +#line 5846 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9617,21 +9619,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5861 "reflect.h2" +#line 5863 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5862 "reflect.h2" +#line 5864 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5863 "reflect.h2" +#line 5865 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5865 "reflect.h2" +#line 5867 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5880 "reflect.h2" +#line 5882 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9639,7 +9641,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5887 "reflect.h2" +#line 5889 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9649,22 +9651,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5905 "reflect.h2" +#line 5907 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5910 "reflect.h2" +#line 5912 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5916 "reflect.h2" +#line 5918 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5922 "reflect.h2" +#line 5924 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9673,7 +9675,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5930 "reflect.h2" +#line 5932 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9685,7 +9687,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5941 "reflect.h2" +#line 5943 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9693,7 +9695,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5948 "reflect.h2" +#line 5950 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9714,7 +9716,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5969 "reflect.h2" +#line 5971 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9724,7 +9726,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5979 "reflect.h2" +#line 5981 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9747,33 +9749,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6003 "reflect.h2" +#line 6005 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6009 "reflect.h2" +#line 6011 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6013 "reflect.h2" +#line 6015 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6019 "reflect.h2" +#line 6021 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6027 "reflect.h2" +#line 6029 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9782,7 +9784,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6035 "reflect.h2" +#line 6037 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9791,22 +9793,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6045 "reflect.h2" +#line 6047 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6049 "reflect.h2" +#line 6051 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6053 "reflect.h2" +#line 6055 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6057 "reflect.h2" +#line 6059 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9830,18 +9832,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6082 "reflect.h2" +#line 6084 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6097 "reflect.h2" +#line 6099 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6099 "reflect.h2" +#line 6101 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9852,15 +9854,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6114 "reflect.h2" +#line 6116 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6117 "reflect.h2" +#line 6119 "reflect.h2" } -#line 6119 "reflect.h2" +#line 6121 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9878,7 +9880,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6136 "reflect.h2" +#line 6138 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9886,7 +9888,7 @@ generation_function_context::generation_function_context(){} } } -#line 6143 "reflect.h2" +#line 6145 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9900,7 +9902,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6156 "reflect.h2" +#line 6158 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9916,14 +9918,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6177 "reflect.h2" +#line 6179 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6179 "reflect.h2" +#line 6181 "reflect.h2" } -#line 6181 "reflect.h2" +#line 6183 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9932,11 +9934,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6196 "reflect.h2" +#line 6198 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6198 "reflect.h2" +#line 6200 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9944,7 +9946,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6205 "reflect.h2" +#line 6207 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9953,37 +9955,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6213 "reflect.h2" +#line 6215 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6227 "reflect.h2" +#line 6229 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6231 "reflect.h2" +#line 6233 "reflect.h2" } -#line 6233 "reflect.h2" +#line 6235 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6237 "reflect.h2" +#line 6239 "reflect.h2" } -#line 6239 "reflect.h2" +#line 6241 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6243 "reflect.h2" +#line 6245 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9992,14 +9994,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6249 "reflect.h2" +#line 6251 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6254 "reflect.h2" +#line 6256 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10012,7 +10014,7 @@ size_t i{0}; } } -#line 6266 "reflect.h2" +#line 6268 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10034,7 +10036,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6287 "reflect.h2" +#line 6289 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10053,7 +10055,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6305 "reflect.h2" +#line 6307 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10069,14 +10071,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6320 "reflect.h2" +#line 6322 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6326 "reflect.h2" +#line 6328 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10084,19 +10086,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6343 "reflect.h2" +#line 6345 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6344 "reflect.h2" +#line 6346 "reflect.h2" { -#line 6349 "reflect.h2" +#line 6351 "reflect.h2" } -#line 6352 "reflect.h2" +#line 6354 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10222,7 +10224,7 @@ size_t i{0}; ); } -#line 6477 "reflect.h2" +#line 6479 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10232,13 +10234,13 @@ size_t i{0}; ); } -#line 6486 "reflect.h2" +#line 6488 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6491 "reflect.h2" +#line 6493 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10249,12 +10251,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6503 "reflect.h2" +#line 6505 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6508 "reflect.h2" +#line 6510 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10288,7 +10290,7 @@ size_t i{0}; } -#line 6544 "reflect.h2" +#line 6546 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10297,19 +10299,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6567 "reflect.h2" +#line 6569 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6568 "reflect.h2" +#line 6570 "reflect.h2" { -#line 6573 "reflect.h2" +#line 6575 "reflect.h2" } -#line 6575 "reflect.h2" +#line 6577 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10411,19 +10413,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6676 "reflect.h2" +#line 6678 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6680 "reflect.h2" +#line 6682 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6704 "reflect.h2" +#line 6706 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10442,7 +10444,7 @@ size_t i{0}; return r; } -#line 6722 "reflect.h2" +#line 6724 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10457,7 +10459,7 @@ size_t i{0}; return r; } -#line 6736 "reflect.h2" +#line 6738 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10617,7 +10619,7 @@ size_t i{0}; } } -#line 6895 "reflect.h2" +#line 6897 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10626,7 +10628,7 @@ size_t i{0}; return r; } -#line 6903 "reflect.h2" +#line 6905 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10645,7 +10647,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6921 "reflect.h2" +#line 6923 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10677,7 +10679,7 @@ size_t i{0}; } } -#line 6952 "reflect.h2" +#line 6954 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10688,7 +10690,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6964 "reflect.h2" +#line 6966 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10727,7 +10729,7 @@ size_t i{0}; return r; } -#line 7005 "reflect.h2" +#line 7007 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10745,7 +10747,7 @@ size_t i{0}; }} } -#line 7025 "reflect.h2" +#line 7027 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10759,16 +10761,16 @@ size_t i{0}; } } -#line 7051 "reflect.h2" +#line 7053 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7054 "reflect.h2" +#line 7056 "reflect.h2" } -#line 7056 "reflect.h2" +#line 7058 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10780,7 +10782,7 @@ size_t i{0}; } } -#line 7067 "reflect.h2" +#line 7069 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10788,14 +10790,14 @@ size_t i{0}; return r; } -#line 7074 "reflect.h2" +#line 7076 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7082 "reflect.h2" +#line 7084 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10821,7 +10823,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7110 "reflect.h2" +#line 7112 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10847,11 +10849,11 @@ size_t i{0}; return r; } -#line 7147 "reflect.h2" +#line 7149 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7149 "reflect.h2" +#line 7151 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10925,7 +10927,7 @@ size_t i{0}; return nullptr; } -#line 7222 "reflect.h2" +#line 7224 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10938,7 +10940,7 @@ size_t i{0}; }} } -#line 7234 "reflect.h2" +#line 7236 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10952,7 +10954,7 @@ size_t i{0}; }} } -#line 7247 "reflect.h2" +#line 7249 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10972,7 +10974,7 @@ size_t i{0}; return r; } -#line 7266 "reflect.h2" +#line 7268 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10983,7 +10985,7 @@ size_t i{0}; return r; } -#line 7276 "reflect.h2" +#line 7278 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10995,14 +10997,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7287 "reflect.h2" +#line 7289 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7299 "reflect.h2" +#line 7301 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11026,7 +11028,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7323 "reflect.h2" +#line 7325 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11036,7 +11038,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7335 "reflect.h2" +#line 7337 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11052,7 +11054,7 @@ size_t i{0}; } } -#line 7355 "reflect.h2" +#line 7357 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11070,15 +11072,15 @@ size_t i{0}; }} } -#line 7391 "reflect.h2" +#line 7393 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7394 "reflect.h2" +#line 7396 "reflect.h2" } -#line 7396 "reflect.h2" +#line 7398 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11114,7 +11116,7 @@ size_t i{0}; return source; } -#line 7431 "reflect.h2" +#line 7433 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11130,7 +11132,7 @@ size_t i{0}; } } -#line 7447 "reflect.h2" +#line 7449 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11139,7 +11141,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11194,7 +11196,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7516 "reflect.h2" +#line 7518 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11316,7 +11318,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7638 "reflect.h2" +#line 7640 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index f52a448df..1962e4fbb 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4681,7 +4681,7 @@ autodiff_expression_handler: type = { { if primary.is_identifier() { primal_expr = primary.to_string(); - fwd_expr = primary.to_string() + ctx*.suffix; + fwd_expr = add_suffix_if_not_wildcard(primal_expr); } else if primary.is_expression_list() { if primary.as_expression_list().is_empty() { @@ -4858,7 +4858,9 @@ autodiff_stmt_handler: type = { { // If this is not an assignment to a parameter or return object, skip it lhs_rhs := expr.get_lhs_rhs_if_simple_assignment(); - lhs := lhs_rhs.lhs.get_first_token_ignoring_this(); + + h_lhs: autodiff_expression_handler = (ctx); + h_lhs.pre_traverse(lhs_rhs.lhs); assignment := expr.as_assignment_expression(); @@ -4873,7 +4875,7 @@ autodiff_stmt_handler: type = { h: autodiff_expression_handler = (ctx); h.pre_traverse(assignment_terms[1].get_term()); - h.gen_assignment(lhs.to_string()); + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr); append(h); } else { From bc3597aa8f2133783b0931c4f0c5785a9ab4565f Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 10:56:25 +0200 Subject: [PATCH 34/54] Moved assignment handling code to proper traverse function. --- source/reflect.h | 916 +++++++++++++++++++++++----------------------- source/reflect.h2 | 40 +- 2 files changed, 460 insertions(+), 496 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 2fc1fff80..59a78de82 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -129,80 +129,80 @@ class autodiff_expression_handler; #line 4708 "reflect.h2" class autodiff_stmt_handler; -#line 4982 "reflect.h2" +#line 4964 "reflect.h2" class autodiff_declaration_handler; -#line 5218 "reflect.h2" +#line 5200 "reflect.h2" class expression_flags; -#line 5234 "reflect.h2" +#line 5216 "reflect.h2" class regex_token; -#line 5261 "reflect.h2" +#line 5243 "reflect.h2" class regex_token_check; -#line 5282 "reflect.h2" +#line 5264 "reflect.h2" class regex_token_code; -#line 5303 "reflect.h2" +#line 5285 "reflect.h2" class regex_token_empty; -#line 5321 "reflect.h2" +#line 5303 "reflect.h2" class regex_token_list; -#line 5373 "reflect.h2" +#line 5355 "reflect.h2" class parse_context_group_state; -#line 5434 "reflect.h2" +#line 5416 "reflect.h2" class parse_context_branch_reset_state; -#line 5477 "reflect.h2" +#line 5459 "reflect.h2" class parse_context; -#line 5878 "reflect.h2" +#line 5860 "reflect.h2" class generation_function_context; -#line 5896 "reflect.h2" +#line 5878 "reflect.h2" class generation_context; -#line 6095 "reflect.h2" +#line 6077 "reflect.h2" class alternative_token; -#line 6110 "reflect.h2" +#line 6092 "reflect.h2" class alternative_token_gen; -#line 6175 "reflect.h2" +#line 6157 "reflect.h2" class any_token; -#line 6192 "reflect.h2" +#line 6174 "reflect.h2" class atomic_group_token; -#line 6222 "reflect.h2" +#line 6204 "reflect.h2" class char_token; -#line 6337 "reflect.h2" +#line 6319 "reflect.h2" class class_token; -#line 6561 "reflect.h2" +#line 6543 "reflect.h2" class group_ref_token; -#line 6698 "reflect.h2" +#line 6680 "reflect.h2" class group_token; -#line 7045 "reflect.h2" +#line 7027 "reflect.h2" class lookahead_lookbehind_token; -#line 7140 "reflect.h2" +#line 7122 "reflect.h2" class range_token; -#line 7297 "reflect.h2" +#line 7279 "reflect.h2" class special_range_token; -#line 7383 "reflect.h2" +#line 7365 "reflect.h2" template class regex_generator; -#line 7640 "reflect.h2" +#line 7622 "reflect.h2" } } @@ -1953,63 +1953,63 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba #line 4856 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4886 "reflect.h2" +#line 4860 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4891 "reflect.h2" +#line 4873 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4895 "reflect.h2" +#line 4877 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4899 "reflect.h2" +#line 4881 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4903 "reflect.h2" +#line 4885 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4907 "reflect.h2" +#line 4889 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4911 "reflect.h2" +#line 4893 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4915 "reflect.h2" +#line 4897 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4919 "reflect.h2" +#line 4901 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4923 "reflect.h2" +#line 4905 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4927 "reflect.h2" +#line 4909 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4931 "reflect.h2" +#line 4913 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4935 "reflect.h2" +#line 4917 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4939 "reflect.h2" +#line 4921 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4944 "reflect.h2" +#line 4926 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4976 "reflect.h2" +#line 4958 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4980 "reflect.h2" +#line 4962 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4986 "reflect.h2" +#line 4968 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2019,37 +2019,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4998 "reflect.h2" +#line 4980 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5003 "reflect.h2" +#line 4985 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5067 "reflect.h2" +#line 5049 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5093 "reflect.h2" +#line 5075 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5115 "reflect.h2" +#line 5097 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5120 "reflect.h2" +#line 5102 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5123 "reflect.h2" +#line 5105 "reflect.h2" }; -#line 5126 "reflect.h2" +#line 5108 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5214 "reflect.h2" +#line 5196 "reflect.h2" using error_func = std::function x)>; -#line 5218 "reflect.h2" +#line 5200 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2084,20 +2084,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5226 "reflect.h2" +#line 5208 "reflect.h2" }; -#line 5234 "reflect.h2" +#line 5216 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5242 "reflect.h2" +#line 5224 "reflect.h2" public: explicit regex_token(); -#line 5247 "reflect.h2" +#line 5229 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2109,103 +2109,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5253 "reflect.h2" +#line 5235 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5259 "reflect.h2" +#line 5241 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5265 "reflect.h2" +#line 5247 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5272 "reflect.h2" +#line 5254 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5276 "reflect.h2" +#line 5258 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5277 "reflect.h2" +#line 5259 "reflect.h2" }; -#line 5280 "reflect.h2" +#line 5262 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5286 "reflect.h2" +#line 5268 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5293 "reflect.h2" +#line 5275 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5297 "reflect.h2" +#line 5279 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5298 "reflect.h2" +#line 5280 "reflect.h2" }; -#line 5301 "reflect.h2" +#line 5283 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5307 "reflect.h2" +#line 5289 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5311 "reflect.h2" +#line 5293 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5315 "reflect.h2" +#line 5297 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5316 "reflect.h2" +#line 5298 "reflect.h2" }; -#line 5319 "reflect.h2" +#line 5301 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5325 "reflect.h2" +#line 5307 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5332 "reflect.h2" +#line 5314 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5338 "reflect.h2" +#line 5320 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5344 "reflect.h2" +#line 5326 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5352 "reflect.h2" +#line 5334 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2213,10 +2213,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5364 "reflect.h2" +#line 5346 "reflect.h2" }; -#line 5367 "reflect.h2" +#line 5349 "reflect.h2" // // Parse and generation context. // @@ -2232,33 +2232,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5387 "reflect.h2" +#line 5369 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5394 "reflect.h2" +#line 5376 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5406 "reflect.h2" +#line 5388 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5411 "reflect.h2" +#line 5393 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5415 "reflect.h2" +#line 5397 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5429 "reflect.h2" +#line 5411 "reflect.h2" }; -#line 5432 "reflect.h2" +#line 5414 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2271,25 +2271,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5450 "reflect.h2" +#line 5432 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5456 "reflect.h2" +#line 5438 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5463 "reflect.h2" +#line 5445 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5470 "reflect.h2" +#line 5452 "reflect.h2" }; -#line 5473 "reflect.h2" +#line 5455 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2305,7 +2305,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5489 "reflect.h2" +#line 5471 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2313,64 +2313,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5500 "reflect.h2" +#line 5482 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5513 "reflect.h2" +#line 5495 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5521 "reflect.h2" +#line 5503 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5525 "reflect.h2" +#line 5507 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5529 "reflect.h2" +#line 5511 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5541 "reflect.h2" +#line 5523 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5548 "reflect.h2" +#line 5530 "reflect.h2" public: auto next_alternative() & -> void; -#line 5554 "reflect.h2" +#line 5536 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5560 "reflect.h2" +#line 5542 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5564 "reflect.h2" +#line 5546 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5575 "reflect.h2" +#line 5557 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5579 "reflect.h2" +#line 5561 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5585 "reflect.h2" +#line 5567 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5589 "reflect.h2" +#line 5571 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5596 "reflect.h2" +#line 5578 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5607 "reflect.h2" +#line 5589 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2378,51 +2378,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5651 "reflect.h2" +#line 5633 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5663 "reflect.h2" +#line 5645 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5676 "reflect.h2" +#line 5658 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5699 "reflect.h2" +#line 5681 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5716 "reflect.h2" +#line 5698 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5737 "reflect.h2" +#line 5719 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5747 "reflect.h2" +#line 5729 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5751 "reflect.h2" +#line 5733 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5807 "reflect.h2" +#line 5789 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5846 "reflect.h2" +#line 5828 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5861 "reflect.h2" +#line 5843 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2434,10 +2434,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5872 "reflect.h2" +#line 5854 "reflect.h2" }; -#line 5875 "reflect.h2" +#line 5857 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2447,16 +2447,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5889 "reflect.h2" +#line 5871 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5892 "reflect.h2" +#line 5874 "reflect.h2" }; -#line 5895 "reflect.h2" +#line 5877 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2476,68 +2476,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5917 "reflect.h2" +#line 5899 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5923 "reflect.h2" +#line 5905 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5932 "reflect.h2" +#line 5914 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5943 "reflect.h2" +#line 5925 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5950 "reflect.h2" +#line 5932 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5970 "reflect.h2" +#line 5952 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5980 "reflect.h2" +#line 5962 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6003 "reflect.h2" +#line 5985 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6011 "reflect.h2" +#line 5993 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6015 "reflect.h2" +#line 5997 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6021 "reflect.h2" +#line 6003 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6027 "reflect.h2" +#line 6009 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6037 "reflect.h2" +#line 6019 "reflect.h2" public: auto finish_context() & -> void; -#line 6045 "reflect.h2" +#line 6027 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6051 "reflect.h2" +#line 6033 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6055 "reflect.h2" +#line 6037 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6059 "reflect.h2" +#line 6041 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6083 "reflect.h2" +#line 6065 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2545,7 +2545,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6089 "reflect.h2" +#line 6071 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2565,27 +2565,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6108 "reflect.h2" +#line 6090 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6114 "reflect.h2" +#line 6096 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6121 "reflect.h2" +#line 6103 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6138 "reflect.h2" +#line 6120 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6145 "reflect.h2" +#line 6127 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6158 "reflect.h2" +#line 6140 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2593,19 +2593,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6170 "reflect.h2" +#line 6152 "reflect.h2" }; -#line 6173 "reflect.h2" +#line 6155 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6179 "reflect.h2" +#line 6161 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6183 "reflect.h2" +#line 6165 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2613,7 +2613,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6188 "reflect.h2" +#line 6170 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2621,17 +2621,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6196 "reflect.h2" +#line 6178 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6207 "reflect.h2" +#line 6189 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6215 "reflect.h2" +#line 6197 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2639,7 +2639,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6218 "reflect.h2" +#line 6200 "reflect.h2" }; // Regex syntax: a @@ -2647,34 +2647,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6226 "reflect.h2" +#line 6208 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6235 "reflect.h2" +#line 6217 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6241 "reflect.h2" +#line 6223 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6245 "reflect.h2" +#line 6227 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6268 "reflect.h2" +#line 6250 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6289 "reflect.h2" +#line 6271 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6307 "reflect.h2" +#line 6289 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6322 "reflect.h2" +#line 6304 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6328 "reflect.h2" +#line 6310 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2682,33 +2682,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6332 "reflect.h2" +#line 6314 "reflect.h2" }; -#line 6335 "reflect.h2" +#line 6317 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6341 "reflect.h2" +#line 6323 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6353 "reflect.h2" +#line 6335 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6479 "reflect.h2" +#line 6461 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6488 "reflect.h2" +#line 6470 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6493 "reflect.h2" +#line 6475 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2716,20 +2716,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6500 "reflect.h2" +#line 6482 "reflect.h2" }; -#line 6503 "reflect.h2" +#line 6485 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6544 "reflect.h2" +#line 6526 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6555 "reflect.h2" +#line 6537 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2739,20 +2739,20 @@ class class_token class group_ref_token : public regex_token { -#line 6565 "reflect.h2" +#line 6547 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6577 "reflect.h2" +#line 6559 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6678 "reflect.h2" +#line 6660 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6682 "reflect.h2" +#line 6664 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2760,10 +2760,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6685 "reflect.h2" +#line 6667 "reflect.h2" }; -#line 6688 "reflect.h2" +#line 6670 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2777,29 +2777,29 @@ class group_ref_token class group_token : public regex_token { -#line 6702 "reflect.h2" +#line 6684 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6724 "reflect.h2" +#line 6706 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6738 "reflect.h2" +#line 6720 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6897 "reflect.h2" +#line 6879 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6905 "reflect.h2" +#line 6887 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6923 "reflect.h2" +#line 6905 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6954 "reflect.h2" +#line 6936 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2808,25 +2808,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6961 "reflect.h2" +#line 6943 "reflect.h2" }; -#line 6964 "reflect.h2" +#line 6946 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7005 "reflect.h2" +#line 6987 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7025 "reflect.h2" +#line 7007 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7041 "reflect.h2" +#line 7023 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2834,20 +2834,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7049 "reflect.h2" +#line 7031 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7058 "reflect.h2" +#line 7040 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7069 "reflect.h2" +#line 7051 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7076 "reflect.h2" +#line 7058 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2855,26 +2855,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7079 "reflect.h2" +#line 7061 "reflect.h2" }; -#line 7082 "reflect.h2" +#line 7064 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7110 "reflect.h2" +#line 7092 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7138 "reflect.h2" +#line 7120 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7144 "reflect.h2" +#line 7126 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2884,22 +2884,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7224 "reflect.h2" +#line 7206 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7236 "reflect.h2" +#line 7218 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7249 "reflect.h2" +#line 7231 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7268 "reflect.h2" +#line 7250 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7278 "reflect.h2" +#line 7260 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7289 "reflect.h2" +#line 7271 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2907,16 +2907,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7292 "reflect.h2" +#line 7274 "reflect.h2" }; -#line 7295 "reflect.h2" +#line 7277 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7301 "reflect.h2" +#line 7283 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2925,7 +2925,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7331 "reflect.h2" +#line 7313 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2934,14 +2934,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7353 "reflect.h2" +#line 7335 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7375 "reflect.h2" +#line 7357 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2962,24 +2962,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7398 "reflect.h2" +#line 7380 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7433 "reflect.h2" +#line 7415 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7447 "reflect.h2" +#line 7429 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7459 "reflect.h2" +#line 7441 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7514 "reflect.h2" +#line 7496 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2990,7 +2990,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7640 "reflect.h2" +#line 7622 "reflect.h2" } } @@ -8533,108 +8533,90 @@ auto i{0}; #line 4856 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ - if (CPP2_UFCS(is_simple_assignment)(expr)) - { - // If this is not an assignment to a parameter or return object, skip it - auto lhs_rhs {CPP2_UFCS(get_lhs_rhs_if_simple_assignment)(expr)}; - - autodiff_expression_handler h_lhs {ctx}; - CPP2_UFCS(pre_traverse)(h_lhs, cpp2::move(lhs_rhs).lhs); - - auto assignment {CPP2_UFCS(as_assignment_expression)(expr)}; - - // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression - auto assignment_terms {CPP2_UFCS(get_terms)(cpp2::move(assignment))}; - if (CPP2_UFCS(ssize)(assignment_terms) != 2) { - CPP2_UFCS(error)(mf, "an assignment must have exactly one right-hand side expression"); - } - - // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each - // @ is one of a list of operators at the same grammar precedence - - autodiff_expression_handler h {ctx}; - CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, cpp2::move(h_lhs).fwd_expr); - append(cpp2::move(h)); - } - else { - base::traverse(expr); - } + base::traverse(expr); } -#line 4886 "reflect.h2" +#line 4860 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - // TDOO: Move meta::expression logic here - CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled as standalone statements.."); + autodiff_expression_handler h_lhs {ctx}; + CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); + + // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression + auto assignment_terms {CPP2_UFCS(get_terms)(binexpr)}; + + autodiff_expression_handler h {ctx}; + CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, cpp2::move(h_lhs).fwd_expr); + append(cpp2::move(h)); } -#line 4891 "reflect.h2" +#line 4873 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); } -#line 4895 "reflect.h2" +#line 4877 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); } -#line 4899 "reflect.h2" +#line 4881 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); } -#line 4903 "reflect.h2" +#line 4885 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); } -#line 4907 "reflect.h2" +#line 4889 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); } -#line 4911 "reflect.h2" +#line 4893 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); } -#line 4915 "reflect.h2" +#line 4897 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); } -#line 4919 "reflect.h2" +#line 4901 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); } -#line 4923 "reflect.h2" +#line 4905 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); } -#line 4927 "reflect.h2" +#line 4909 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4931 "reflect.h2" +#line 4913 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4935 "reflect.h2" +#line 4917 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4939 "reflect.h2" +#line 4921 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4944 "reflect.h2" +#line 4926 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8643,7 +8625,7 @@ auto i{0}; { auto i{0}; -#line 4951 "reflect.h2" +#line 4933 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8658,7 +8640,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4964 "reflect.h2" +#line 4946 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8671,27 +8653,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4976 "reflect.h2" +#line 4958 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4993 "reflect.h2" +#line 4975 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4996 "reflect.h2" +#line 4978 "reflect.h2" } -#line 4998 "reflect.h2" +#line 4980 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5003 "reflect.h2" +#line 4985 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8735,10 +8717,10 @@ auto i{0}; return ; } -#line 5047 "reflect.h2" +#line 5029 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5050 "reflect.h2" +#line 5032 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8755,7 +8737,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5067 "reflect.h2" +#line 5049 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -8781,7 +8763,7 @@ auto i{0}; diff = ""; } -#line 5093 "reflect.h2" +#line 5075 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -8803,17 +8785,17 @@ auto i{0}; } } -#line 5115 "reflect.h2" +#line 5097 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5120 "reflect.h2" +#line 5102 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5126 "reflect.h2" +#line 5108 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8849,7 +8831,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5162 "reflect.h2" +#line 5144 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8978,7 +8960,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5200 "reflect.h2" +#line 5182 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8994,11 +8976,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5216 "reflect.h2" +#line 5198 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5220 "reflect.h2" +#line 5202 "reflect.h2" // mod: i // mod: m // mod: s @@ -9006,116 +8988,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5229 "reflect.h2" +#line 5211 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5238 "reflect.h2" +#line 5220 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5240 "reflect.h2" +#line 5222 "reflect.h2" } -#line 5242 "reflect.h2" +#line 5224 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5244 "reflect.h2" +#line 5226 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5250 "reflect.h2" +#line 5232 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5251 "reflect.h2" +#line 5233 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5252 "reflect.h2" +#line 5234 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5267 "reflect.h2" +#line 5249 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5270 "reflect.h2" +#line 5252 "reflect.h2" } -#line 5272 "reflect.h2" +#line 5254 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5276 "reflect.h2" +#line 5258 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5288 "reflect.h2" +#line 5270 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5291 "reflect.h2" +#line 5273 "reflect.h2" } -#line 5293 "reflect.h2" +#line 5275 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5297 "reflect.h2" +#line 5279 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5307 "reflect.h2" +#line 5289 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5309 "reflect.h2" +#line 5291 "reflect.h2" } -#line 5311 "reflect.h2" +#line 5293 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5315 "reflect.h2" +#line 5297 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5327 "reflect.h2" +#line 5309 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5330 "reflect.h2" +#line 5312 "reflect.h2" } -#line 5332 "reflect.h2" +#line 5314 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5338 "reflect.h2" +#line 5320 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5344 "reflect.h2" +#line 5326 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9124,7 +9106,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5352 "reflect.h2" +#line 5334 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9140,7 +9122,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5380 "reflect.h2" +#line 5362 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9148,14 +9130,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5388 "reflect.h2" +#line 5370 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5395 "reflect.h2" +#line 5377 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9167,15 +9149,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5407 "reflect.h2" +#line 5389 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5412 "reflect.h2" +#line 5394 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5416 "reflect.h2" +#line 5398 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9196,7 +9178,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5442 "reflect.h2" +#line 5424 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9205,20 +9187,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5451 "reflect.h2" +#line 5433 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5457 "reflect.h2" +#line 5439 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5464 "reflect.h2" +#line 5446 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9233,16 +9215,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5494 "reflect.h2" +#line 5476 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5498 "reflect.h2" +#line 5480 "reflect.h2" } -#line 5504 "reflect.h2" +#line 5486 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9252,7 +9234,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5514 "reflect.h2" +#line 5496 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9260,17 +9242,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5521 "reflect.h2" +#line 5503 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5525 "reflect.h2" +#line 5507 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5532 "reflect.h2" +#line 5514 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9280,7 +9262,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5541 "reflect.h2" +#line 5523 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9288,24 +9270,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5548 "reflect.h2" +#line 5530 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5556 "reflect.h2" +#line 5538 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5560 "reflect.h2" +#line 5542 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5564 "reflect.h2" +#line 5546 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9317,22 +9299,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5575 "reflect.h2" +#line 5557 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5581 "reflect.h2" +#line 5563 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5585 "reflect.h2" +#line 5567 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5589 "reflect.h2" +#line 5571 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9340,7 +9322,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5596 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9352,10 +9334,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5609 "reflect.h2" +#line 5591 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5612 "reflect.h2" +#line 5594 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9395,7 +9377,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5652 "reflect.h2" +#line 5634 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9407,14 +9389,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5663 "reflect.h2" +#line 5645 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5664 "reflect.h2" +#line 5646 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5665 "reflect.h2" +#line 5647 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5667 "reflect.h2" +#line 5649 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9424,10 +9406,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5676 "reflect.h2" +#line 5658 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5678 "reflect.h2" +#line 5660 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9449,14 +9431,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5699 "reflect.h2" +#line 5681 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5700 "reflect.h2" +#line 5682 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5701 "reflect.h2" +#line 5683 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5703 "reflect.h2" +#line 5685 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9470,7 +9452,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5716 "reflect.h2" +#line 5698 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9492,7 +9474,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5737 "reflect.h2" +#line 5719 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9503,12 +9485,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5747 "reflect.h2" +#line 5729 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5748 "reflect.h2" +#line 5730 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5753 "reflect.h2" +#line 5735 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9563,7 +9545,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5807 "reflect.h2" +#line 5789 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9603,7 +9585,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5846 "reflect.h2" +#line 5828 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9619,21 +9601,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5863 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5864 "reflect.h2" +#line 5846 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5865 "reflect.h2" +#line 5847 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5867 "reflect.h2" +#line 5849 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5882 "reflect.h2" +#line 5864 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9641,7 +9623,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5889 "reflect.h2" +#line 5871 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9651,22 +9633,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5907 "reflect.h2" +#line 5889 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5912 "reflect.h2" +#line 5894 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5918 "reflect.h2" +#line 5900 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5924 "reflect.h2" +#line 5906 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9675,7 +9657,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5932 "reflect.h2" +#line 5914 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9687,7 +9669,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5943 "reflect.h2" +#line 5925 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9695,7 +9677,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5950 "reflect.h2" +#line 5932 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9716,7 +9698,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5971 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9726,7 +9708,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5981 "reflect.h2" +#line 5963 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9749,33 +9731,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6005 "reflect.h2" +#line 5987 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6011 "reflect.h2" +#line 5993 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6015 "reflect.h2" +#line 5997 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6021 "reflect.h2" +#line 6003 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6029 "reflect.h2" +#line 6011 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9784,7 +9766,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6037 "reflect.h2" +#line 6019 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9793,22 +9775,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6047 "reflect.h2" +#line 6029 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6051 "reflect.h2" +#line 6033 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6055 "reflect.h2" +#line 6037 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6059 "reflect.h2" +#line 6041 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9832,18 +9814,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6084 "reflect.h2" +#line 6066 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6099 "reflect.h2" +#line 6081 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6101 "reflect.h2" +#line 6083 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9854,15 +9836,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6116 "reflect.h2" +#line 6098 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6119 "reflect.h2" +#line 6101 "reflect.h2" } -#line 6121 "reflect.h2" +#line 6103 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9880,7 +9862,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6138 "reflect.h2" +#line 6120 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9888,7 +9870,7 @@ generation_function_context::generation_function_context(){} } } -#line 6145 "reflect.h2" +#line 6127 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9902,7 +9884,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6158 "reflect.h2" +#line 6140 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9918,14 +9900,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6179 "reflect.h2" +#line 6161 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6181 "reflect.h2" +#line 6163 "reflect.h2" } -#line 6183 "reflect.h2" +#line 6165 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9934,11 +9916,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6198 "reflect.h2" +#line 6180 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6200 "reflect.h2" +#line 6182 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9946,7 +9928,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6207 "reflect.h2" +#line 6189 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9955,37 +9937,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6215 "reflect.h2" +#line 6197 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6229 "reflect.h2" +#line 6211 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6233 "reflect.h2" +#line 6215 "reflect.h2" } -#line 6235 "reflect.h2" +#line 6217 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6239 "reflect.h2" +#line 6221 "reflect.h2" } -#line 6241 "reflect.h2" +#line 6223 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6245 "reflect.h2" +#line 6227 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9994,14 +9976,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6251 "reflect.h2" +#line 6233 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6256 "reflect.h2" +#line 6238 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10014,7 +9996,7 @@ size_t i{0}; } } -#line 6268 "reflect.h2" +#line 6250 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10036,7 +10018,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6289 "reflect.h2" +#line 6271 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10055,7 +10037,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6307 "reflect.h2" +#line 6289 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10071,14 +10053,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6322 "reflect.h2" +#line 6304 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6328 "reflect.h2" +#line 6310 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10086,19 +10068,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6345 "reflect.h2" +#line 6327 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6346 "reflect.h2" +#line 6328 "reflect.h2" { -#line 6351 "reflect.h2" +#line 6333 "reflect.h2" } -#line 6354 "reflect.h2" +#line 6336 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10224,7 +10206,7 @@ size_t i{0}; ); } -#line 6479 "reflect.h2" +#line 6461 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10234,13 +10216,13 @@ size_t i{0}; ); } -#line 6488 "reflect.h2" +#line 6470 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6493 "reflect.h2" +#line 6475 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10251,12 +10233,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6505 "reflect.h2" +#line 6487 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6510 "reflect.h2" +#line 6492 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10290,7 +10272,7 @@ size_t i{0}; } -#line 6546 "reflect.h2" +#line 6528 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10299,19 +10281,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6569 "reflect.h2" +#line 6551 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6570 "reflect.h2" +#line 6552 "reflect.h2" { -#line 6575 "reflect.h2" +#line 6557 "reflect.h2" } -#line 6577 "reflect.h2" +#line 6559 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10413,19 +10395,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6678 "reflect.h2" +#line 6660 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6682 "reflect.h2" +#line 6664 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6706 "reflect.h2" +#line 6688 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10444,7 +10426,7 @@ size_t i{0}; return r; } -#line 6724 "reflect.h2" +#line 6706 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10459,7 +10441,7 @@ size_t i{0}; return r; } -#line 6738 "reflect.h2" +#line 6720 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10619,7 +10601,7 @@ size_t i{0}; } } -#line 6897 "reflect.h2" +#line 6879 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10628,7 +10610,7 @@ size_t i{0}; return r; } -#line 6905 "reflect.h2" +#line 6887 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10647,7 +10629,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6923 "reflect.h2" +#line 6905 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10679,7 +10661,7 @@ size_t i{0}; } } -#line 6954 "reflect.h2" +#line 6936 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10690,7 +10672,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6966 "reflect.h2" +#line 6948 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10729,7 +10711,7 @@ size_t i{0}; return r; } -#line 7007 "reflect.h2" +#line 6989 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10747,7 +10729,7 @@ size_t i{0}; }} } -#line 7027 "reflect.h2" +#line 7009 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10761,16 +10743,16 @@ size_t i{0}; } } -#line 7053 "reflect.h2" +#line 7035 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7056 "reflect.h2" +#line 7038 "reflect.h2" } -#line 7058 "reflect.h2" +#line 7040 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10782,7 +10764,7 @@ size_t i{0}; } } -#line 7069 "reflect.h2" +#line 7051 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10790,14 +10772,14 @@ size_t i{0}; return r; } -#line 7076 "reflect.h2" +#line 7058 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7084 "reflect.h2" +#line 7066 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10823,7 +10805,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7112 "reflect.h2" +#line 7094 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10849,11 +10831,11 @@ size_t i{0}; return r; } -#line 7149 "reflect.h2" +#line 7131 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7151 "reflect.h2" +#line 7133 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10927,7 +10909,7 @@ size_t i{0}; return nullptr; } -#line 7224 "reflect.h2" +#line 7206 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10940,7 +10922,7 @@ size_t i{0}; }} } -#line 7236 "reflect.h2" +#line 7218 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10954,7 +10936,7 @@ size_t i{0}; }} } -#line 7249 "reflect.h2" +#line 7231 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10974,7 +10956,7 @@ size_t i{0}; return r; } -#line 7268 "reflect.h2" +#line 7250 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10985,7 +10967,7 @@ size_t i{0}; return r; } -#line 7278 "reflect.h2" +#line 7260 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10997,14 +10979,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7289 "reflect.h2" +#line 7271 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7301 "reflect.h2" +#line 7283 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11028,7 +11010,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7325 "reflect.h2" +#line 7307 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11038,7 +11020,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7337 "reflect.h2" +#line 7319 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11054,7 +11036,7 @@ size_t i{0}; } } -#line 7357 "reflect.h2" +#line 7339 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11072,15 +11054,15 @@ size_t i{0}; }} } -#line 7393 "reflect.h2" +#line 7375 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7396 "reflect.h2" +#line 7378 "reflect.h2" } -#line 7398 "reflect.h2" +#line 7380 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11116,7 +11098,7 @@ size_t i{0}; return source; } -#line 7433 "reflect.h2" +#line 7415 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11132,7 +11114,7 @@ size_t i{0}; } } -#line 7449 "reflect.h2" +#line 7431 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11141,7 +11123,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11196,7 +11178,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7518 "reflect.h2" +#line 7500 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11318,7 +11300,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7640 "reflect.h2" +#line 7622 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 1962e4fbb..a7609091a 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4854,38 +4854,20 @@ autodiff_stmt_handler: type = { } traverse : (override inout this, expr: meta::expression) = { - if expr.is_simple_assignment() - { - // If this is not an assignment to a parameter or return object, skip it - lhs_rhs := expr.get_lhs_rhs_if_simple_assignment(); - - h_lhs: autodiff_expression_handler = (ctx); - h_lhs.pre_traverse(lhs_rhs.lhs); - - assignment := expr.as_assignment_expression(); - - // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression - assignment_terms := assignment.get_terms(); - if assignment_terms.ssize() != 2 { - mf.error( "an assignment must have exactly one right-hand side expression" ); - } - - // Now we handle sequences of binary "expr1 @ expr2 @ ..." where each - // @ is one of a list of operators at the same grammar precedence - - h: autodiff_expression_handler = (ctx); - h.pre_traverse(assignment_terms[1].get_term()); - h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr); - append(h); - } - else { - base::traverse(expr); - } + base::traverse(expr); } traverse: (override inout this, binexpr: meta::assignment_expression) = { - // TDOO: Move meta::expression logic here - binexpr.error( "AD: Assign expressions are not yet handled as standalone statements.." ); + h_lhs: autodiff_expression_handler = (ctx); + h_lhs.pre_traverse(binexpr.get_lhs_postfix_expression()); + + // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression + assignment_terms := binexpr.get_terms(); + + h: autodiff_expression_handler = (ctx); + h.pre_traverse(assignment_terms[1].get_term()); + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr); + append(h); } traverse: (override inout this, binexpr: meta::logical_or_expression) = { From 247a79d504a3bd8a9c552e59deb9e2ba80fada27 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 11:56:46 +0200 Subject: [PATCH 35/54] Added type differentiation for types without member functions. --- .../pure2-autodiff-higher-order.cpp2 | 75 +- .../pure2-autodiff-higher-order.cpp.execution | 16 + .../pure2-autodiff-higher-order.cpp | 353 +++-- .../pure2-autodiff-higher-order.cpp2.output | 59 + .../test-results/pure2-autodiff.cpp | 17 +- .../test-results/pure2-autodiff.cpp2.output | 6 +- source/reflect.h | 1211 +++++++++-------- source/reflect.h2 | 67 +- 8 files changed, 1045 insertions(+), 759 deletions(-) diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index 760704ea0..5d5c466e1 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -1,7 +1,16 @@ - ad_order : int == 6; ad_type : type == cpp2::taylor; +ad_name: namespace = { + +func_outer: (x: double, y: double) -> (ret: double) = { + ret = x + y; +} + +type_outer: type = { + public a: double = 0.0; +} + ad_test: @autodiff<"order=6"> @print type = { add_1: (x: double, y: double) -> (r: double) = { @@ -60,6 +69,10 @@ ad_test: @autodiff<"order=6"> @print type = { r = x * func(x, y); } + func_outer_call: (x: double, y: double) -> (r: double) = { + r = x * func_outer(x, y); + } + sin_call: (x: double, y: double) -> (r: double) = { r = sin(x - y); } @@ -153,6 +166,14 @@ ad_test: @autodiff<"order=6"> @print type = { r = r + t; } } + + type_outer_use: (x: double, y: double) -> (r: double) = { + t : type_outer = (); + t.a = x; + + r = t.a + y; + } +} } write_output: (func: std::string, x: double, x_d: ad_type, y: double, y_d: ad_type, ret) = { @@ -172,29 +193,31 @@ main: () = { y: double = 3.0; y_d: ad_type = 2.0; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("x + y", x, x_d, y, y_d, ad_name::ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_name::ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_name::ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_name::ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_name::ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_name::ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_name::ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_name::ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_name::ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_name::ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_name::ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_name::ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_name::ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_name::ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_name::ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); } diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index f5a4a8c98..c1add3ddc 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -102,6 +102,14 @@ diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.0000 d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): r = -0.841471 d1 = -0.540302 @@ -198,3 +206,11 @@ diff(for loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.0 d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(tye_outer.a + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 023dd8eed..90b7344f6 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -9,147 +9,198 @@ #line 1 "pure2-autodiff-higher-order.cpp2" -#line 5 "pure2-autodiff-higher-order.cpp2" +#line 4 "pure2-autodiff-higher-order.cpp2" +namespace ad_name { + +#line 10 "pure2-autodiff-higher-order.cpp2" +class type_outer; + + class type_outer_d; + + +#line 14 "pure2-autodiff-higher-order.cpp2" class ad_test; +#line 177 "pure2-autodiff-higher-order.cpp2" +} + //=== Cpp2 type definitions and function declarations =========================== #line 1 "pure2-autodiff-higher-order.cpp2" - -#line 2 "pure2-autodiff-higher-order.cpp2" int inline constexpr ad_order{ 6 }; +#line 2 "pure2-autodiff-higher-order.cpp2" using ad_type = cpp2::taylor; +namespace ad_name { +using func_outer_ret = double; + + +#line 6 "pure2-autodiff-higher-order.cpp2" +[[nodiscard]] auto func_outer(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_ret; + +#line 10 "pure2-autodiff-higher-order.cpp2" +class type_outer { + public: double a {0.0}; + public: type_outer() = default; + public: type_outer(type_outer const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(type_outer const&) -> void = delete; + +#line 12 "pure2-autodiff-higher-order.cpp2" +}; + +struct func_outer_d_ret { double ret; cpp2::taylor ret_d; }; + + +[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_d_ret; +class type_outer_d { +public: cpp2::taylor a_d {}; + public: type_outer_d() = default; + public: type_outer_d(type_outer_d const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(type_outer_d const&) -> void = delete; + +}; + +#line 14 "pure2-autodiff-higher-order.cpp2" class ad_test { using add_1_ret = double; -#line 7 "pure2-autodiff-higher-order.cpp2" +#line 16 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 11 "pure2-autodiff-higher-order.cpp2" +#line 20 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 15 "pure2-autodiff-higher-order.cpp2" +#line 24 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 19 "pure2-autodiff-higher-order.cpp2" +#line 28 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 23 "pure2-autodiff-higher-order.cpp2" +#line 32 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 27 "pure2-autodiff-higher-order.cpp2" +#line 36 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 31 "pure2-autodiff-higher-order.cpp2" +#line 40 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 35 "pure2-autodiff-higher-order.cpp2" +#line 44 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 39 "pure2-autodiff-higher-order.cpp2" +#line 48 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 43 "pure2-autodiff-higher-order.cpp2" +#line 52 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 47 "pure2-autodiff-higher-order.cpp2" +#line 56 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 51 "pure2-autodiff-higher-order.cpp2" +#line 60 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 55 "pure2-autodiff-higher-order.cpp2" +#line 64 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 59 "pure2-autodiff-higher-order.cpp2" +#line 68 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; +using func_outer_call_ret = double; + + +#line 72 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 63 "pure2-autodiff-higher-order.cpp2" +#line 76 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 67 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 75 "pure2-autodiff-higher-order.cpp2" +#line 88 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 84 "pure2-autodiff-higher-order.cpp2" +#line 97 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 88 "pure2-autodiff-higher-order.cpp2" +#line 101 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 94 "pure2-autodiff-higher-order.cpp2" +#line 107 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 102 "pure2-autodiff-higher-order.cpp2" +#line 115 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 109 "pure2-autodiff-higher-order.cpp2" +#line 122 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 116 "pure2-autodiff-higher-order.cpp2" +#line 129 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 123 "pure2-autodiff-higher-order.cpp2" +#line 136 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 132 "pure2-autodiff-higher-order.cpp2" +#line 145 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 143 "pure2-autodiff-higher-order.cpp2" +#line 156 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; +using type_outer_use_ret = double; + + +#line 170 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -207,6 +258,10 @@ struct func_call_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret; +struct func_outer_call_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto func_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_call_d_ret; + struct sin_call_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret; @@ -255,132 +310,163 @@ struct for_loop_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto for_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> for_loop_d_ret; +struct type_outer_use_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto type_outer_use_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_use_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 156 "pure2-autodiff-higher-order.cpp2" +#line 176 "pure2-autodiff-higher-order.cpp2" }; +} auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 167 "pure2-autodiff-higher-order.cpp2" +#line 188 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= #line 1 "pure2-autodiff-higher-order.cpp2" +#line 4 "pure2-autodiff-higher-order.cpp2" +namespace ad_name { + +#line 6 "pure2-autodiff-higher-order.cpp2" +[[nodiscard]] auto func_outer(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_ret{ + cpp2::impl::deferred_init ret; #line 7 "pure2-autodiff-higher-order.cpp2" + ret.construct(x + y); +return std::move(ret.value()); } + +[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_d_ret{ + double ret {0.0}; + cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; +ret = x + y; +return { std::move(ret), std::move(ret_d) }; +} + + + +#line 16 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 8 "pure2-autodiff-higher-order.cpp2" +#line 17 "pure2-autodiff-higher-order.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 11 "pure2-autodiff-higher-order.cpp2" +#line 20 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 12 "pure2-autodiff-higher-order.cpp2" +#line 21 "pure2-autodiff-higher-order.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 15 "pure2-autodiff-higher-order.cpp2" +#line 24 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 16 "pure2-autodiff-higher-order.cpp2" +#line 25 "pure2-autodiff-higher-order.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 19 "pure2-autodiff-higher-order.cpp2" +#line 28 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 20 "pure2-autodiff-higher-order.cpp2" +#line 29 "pure2-autodiff-higher-order.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 23 "pure2-autodiff-higher-order.cpp2" +#line 32 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 24 "pure2-autodiff-higher-order.cpp2" +#line 33 "pure2-autodiff-higher-order.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 27 "pure2-autodiff-higher-order.cpp2" +#line 36 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 28 "pure2-autodiff-higher-order.cpp2" +#line 37 "pure2-autodiff-higher-order.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 31 "pure2-autodiff-higher-order.cpp2" +#line 40 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 32 "pure2-autodiff-higher-order.cpp2" +#line 41 "pure2-autodiff-higher-order.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 35 "pure2-autodiff-higher-order.cpp2" +#line 44 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 36 "pure2-autodiff-higher-order.cpp2" +#line 45 "pure2-autodiff-higher-order.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 39 "pure2-autodiff-higher-order.cpp2" +#line 48 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 40 "pure2-autodiff-higher-order.cpp2" +#line 49 "pure2-autodiff-higher-order.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 43 "pure2-autodiff-higher-order.cpp2" +#line 52 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 44 "pure2-autodiff-higher-order.cpp2" +#line 53 "pure2-autodiff-higher-order.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 47 "pure2-autodiff-higher-order.cpp2" +#line 56 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 48 "pure2-autodiff-higher-order.cpp2" +#line 57 "pure2-autodiff-higher-order.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 51 "pure2-autodiff-higher-order.cpp2" +#line 60 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 52 "pure2-autodiff-higher-order.cpp2" +#line 61 "pure2-autodiff-higher-order.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 55 "pure2-autodiff-higher-order.cpp2" +#line 64 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 56 "pure2-autodiff-higher-order.cpp2" +#line 65 "pure2-autodiff-higher-order.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 59 "pure2-autodiff-higher-order.cpp2" +#line 68 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 60 "pure2-autodiff-higher-order.cpp2" +#line 69 "pure2-autodiff-higher-order.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 63 "pure2-autodiff-higher-order.cpp2" +#line 72 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ + cpp2::impl::deferred_init r; +#line 73 "pure2-autodiff-higher-order.cpp2" + r.construct(x * func_outer(x, y)); + return std::move(r.value()); } + +#line 76 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 64 "pure2-autodiff-higher-order.cpp2" +#line 77 "pure2-autodiff-higher-order.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 67 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 68 "pure2-autodiff-higher-order.cpp2" +#line 81 "pure2-autodiff-higher-order.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -388,10 +474,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 75 "pure2-autodiff-higher-order.cpp2" +#line 88 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 76 "pure2-autodiff-higher-order.cpp2" +#line 89 "pure2-autodiff-higher-order.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -400,24 +486,24 @@ auto main() -> int; }return std::move(r.value()); } -#line 84 "pure2-autodiff-higher-order.cpp2" +#line 97 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 88 "pure2-autodiff-higher-order.cpp2" +#line 101 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 89 "pure2-autodiff-higher-order.cpp2" +#line 102 "pure2-autodiff-higher-order.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 94 "pure2-autodiff-higher-order.cpp2" +#line 107 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 95 "pure2-autodiff-higher-order.cpp2" +#line 108 "pure2-autodiff-higher-order.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -425,40 +511,40 @@ auto main() -> int; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 102 "pure2-autodiff-higher-order.cpp2" +#line 115 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 103 "pure2-autodiff-higher-order.cpp2" +#line 116 "pure2-autodiff-higher-order.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 109 "pure2-autodiff-higher-order.cpp2" +#line 122 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 110 "pure2-autodiff-higher-order.cpp2" +#line 123 "pure2-autodiff-higher-order.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 116 "pure2-autodiff-higher-order.cpp2" +#line 129 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 117 "pure2-autodiff-higher-order.cpp2" +#line 130 "pure2-autodiff-higher-order.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 123 "pure2-autodiff-higher-order.cpp2" +#line 136 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 124 "pure2-autodiff-higher-order.cpp2" +#line 137 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -467,10 +553,10 @@ auto main() -> int; }return std::move(r.value()); } -#line 132 "pure2-autodiff-higher-order.cpp2" +#line 145 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 133 "pure2-autodiff-higher-order.cpp2" +#line 146 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -481,10 +567,10 @@ auto main() -> int; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 143 "pure2-autodiff-higher-order.cpp2" +#line 156 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 144 "pure2-autodiff-higher-order.cpp2" +#line 157 "pure2-autodiff-higher-order.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -498,6 +584,16 @@ auto main() -> int; }return std::move(r.value()); } +#line 170 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ + cpp2::impl::deferred_init r; +#line 171 "pure2-autodiff-higher-order.cpp2" + type_outer t {}; + t.a = x; + + r.construct(cpp2::move(t).a + y); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0};r_d = x_d + y_d; @@ -622,6 +718,19 @@ auto temp_1 {func_d(x, x_d, y, y_d)}; return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto ad_test::func_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_call_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1 {func_outer_d(x, x_d, y, y_d)}; + + cpp2::taylor temp_2_d {temp_1.ret_d}; + + double temp_2 {cpp2::move(temp_1).ret}; + r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_2_d), x, temp_2); + r = x * cpp2::move(temp_2); + return { std::move(r), std::move(r_d) }; + } + [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0}; @@ -793,54 +902,76 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; return { std::move(r), std::move(r_d) }; } -#line 158 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::type_outer_use_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_use_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +type_outer_d t_d {}; + + type_outer t {}; + t_d.a_d = x_d; + t.a = x; + + cpp2::taylor temp_1_d {cpp2::move(t_d).a_d}; + + double temp_1 {cpp2::move(t).a}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + +#line 177 "pure2-autodiff-higher-order.cpp2" +} + +#line 179 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 162 "pure2-autodiff-higher-order.cpp2" +#line 183 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 165 "pure2-autodiff-higher-order.cpp2" +#line 186 "pure2-autodiff-higher-order.cpp2" } -#line 167 "pure2-autodiff-higher-order.cpp2" +#line 188 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 170 "pure2-autodiff-higher-order.cpp2" +#line 191 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; ad_type y_d {2.0}; - write_output("x + y", x, x_d, y, y_d, ad_test::add_1_d(x, x_d, y, y_d)); - write_output("x + y + x", x, x_d, y, y_d, ad_test::add_2_d(x, x_d, y, y_d)); - write_output("x - y", x, x_d, y, y_d, ad_test::sub_1_d(x, x_d, y, y_d)); - write_output("x - y - x", x, x_d, y, y_d, ad_test::sub_2_d(x, x_d, y, y_d)); - write_output("x + y - x", x, x_d, y, y_d, ad_test::add_sub_2_d(x, x_d, y, y_d)); - write_output("x * y", x, x_d, y, y_d, ad_test::mul_1_d(x, x_d, y, y_d)); - write_output("x * y * x", x, x_d, y, y_d, ad_test::mul_2_d(x, x_d, y, y_d)); - write_output("x / y", x, x_d, y, y_d, ad_test::div_1_d(x, x_d, y, y_d)); - write_output("x / y / y", x, x_d, y, y_d, ad_test::div_2_d(x, x_d, y, y_d)); - write_output("x * y / x", x, x_d, y, y_d, ad_test::mul_div_2_d(x, x_d, y, y_d)); - write_output("x * (x + y)", x, x_d, y, y_d, ad_test::mul_add_d(x, x_d, y, y_d)); - write_output("x + x * y", x, x_d, y, y_d, ad_test::add_mul_d(x, x_d, y, y_d)); - write_output("x * func(x, y)", x, x_d, y, y_d, ad_test::func_call_d(x, x_d, y, y_d)); - write_output("sin(x - y)", x, x_d, y, y_d, ad_test::sin_call_d(x, x_d, y, y_d)); - write_output("if branch", x, x_d, y, y_d, ad_test::if_branch_d(x, x_d, y, y_d)); - write_output("if else branch", x, x_d, y, y_d, ad_test::if_else_branch_d(x, x_d, y, y_d)); - write_output("direct return", x, x_d, y, y_d, ad_test::direct_return_d(x, x_d, y, y_d)); - write_output("intermediate var", x, x_d, y, y_d, ad_test::intermediate_var_d(x, x_d, y, y_d)); - write_output("intermediate passive var", x, x_d, y, y_d, ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); - write_output("intermediate untyped", x, x_d, y, y_d, ad_test::intermediate_untyped_d(x, x_d, y, y_d)); - write_output("intermediate default init", x, x_d, y, y_d, ad_test::intermediate_default_init_d(x, x_d, y, y_d)); - write_output("intermediate no init", x, x_d, y, y_d, ad_test::intermediate_no_init_d(x, x_d, y, y_d)); - write_output("while loop", x, x_d, y, y_d, ad_test::while_loop_d(x, x_d, y, y_d)); - write_output("do while loop", x, x_d, y, y_d, ad_test::do_while_loop_d(x, x_d, y, y_d)); - write_output("for loop", x, x_d, y, y_d, ad_test::for_loop_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("x + y", x, x_d, y, y_d, ad_name::ad_test::add_1_d(x, x_d, y, y_d)); + write_output("x + y + x", x, x_d, y, y_d, ad_name::ad_test::add_2_d(x, x_d, y, y_d)); + write_output("x - y", x, x_d, y, y_d, ad_name::ad_test::sub_1_d(x, x_d, y, y_d)); + write_output("x - y - x", x, x_d, y, y_d, ad_name::ad_test::sub_2_d(x, x_d, y, y_d)); + write_output("x + y - x", x, x_d, y, y_d, ad_name::ad_test::add_sub_2_d(x, x_d, y, y_d)); + write_output("x * y", x, x_d, y, y_d, ad_name::ad_test::mul_1_d(x, x_d, y, y_d)); + write_output("x * y * x", x, x_d, y, y_d, ad_name::ad_test::mul_2_d(x, x_d, y, y_d)); + write_output("x / y", x, x_d, y, y_d, ad_name::ad_test::div_1_d(x, x_d, y, y_d)); + write_output("x / y / y", x, x_d, y, y_d, ad_name::ad_test::div_2_d(x, x_d, y, y_d)); + write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); + write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); + write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); + write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); + write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); + write_output("if branch", x, x_d, y, y_d, ad_name::ad_test::if_branch_d(x, x_d, y, y_d)); + write_output("if else branch", x, x_d, y, y_d, ad_name::ad_test::if_else_branch_d(x, x_d, y, y_d)); + write_output("direct return", x, x_d, y, y_d, ad_name::ad_test::direct_return_d(x, x_d, y, y_d)); + write_output("intermediate var", x, x_d, y, y_d, ad_name::ad_test::intermediate_var_d(x, x_d, y, y_d)); + write_output("intermediate passive var", x, x_d, y, y_d, ad_name::ad_test::intermediate_passive_var_d(x, x_d, y, y_d)); + write_output("intermediate untyped", x, x_d, y, y_d, ad_name::ad_test::intermediate_untyped_d(x, x_d, y, y_d)); + write_output("intermediate default init", x, x_d, y, y_d, ad_name::ad_test::intermediate_default_init_d(x, x_d, y, y_d)); + write_output("intermediate no init", x, x_d, y, y_d, ad_name::ad_test::intermediate_no_init_d(x, x_d, y, y_d)); + write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); + write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); + write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 1ace0113e..6fcff530d 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -128,6 +128,15 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + func_outer_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func_outer(x, y); + return; + } + sin_call:( in x: double, in y: double, @@ -277,6 +286,17 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + type_outer_use:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: type_outer = (); + t.a = x; + r = t.a + y; + return; + } + add_1_d:( in x: double, in x_d: cpp2::taylor, @@ -500,6 +520,24 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + func_outer_call_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1: _ = func_outer_d(x, x_d, y, y_d); + temp_2_d: cpp2::taylor = temp_1.ret_d; + temp_2: double = temp_1.ret; + r_d = x_d.mul(temp_2_d, x, temp_2); + r = x * temp_2; + return; + } + sin_call_d:( in x: double, in x_d: cpp2::taylor, @@ -751,6 +789,27 @@ ad_test:/* @autodiff<"order=6"> @print */ type = } return; } + + type_outer_use_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: type_outer_d = (); + t: type_outer = (); + t_d.a_d = x_d; + t.a = x; + temp_1_d: cpp2::taylor = t_d.a_d; + temp_1: double = t.a; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 453376fa1..1f556a032 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -12,6 +12,8 @@ namespace ad_name { #line 7 "pure2-autodiff.cpp2" class type_outer; + class type_outer_d; + #line 11 "pure2-autodiff.cpp2" class ad_test; @@ -46,6 +48,13 @@ struct func_outer_d_ret { double ret; double ret_d; }; [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret; +class type_outer_d { +public: double a_d {}; + public: type_outer_d() = default; + public: type_outer_d(type_outer_d const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(type_outer_d const&) -> void = delete; + +}; #line 11 "pure2-autodiff.cpp2" class ad_test { @@ -359,6 +368,8 @@ ret = x + y; return { std::move(ret), std::move(ret_d) }; } + + #line 13 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; @@ -913,13 +924,13 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; [[nodiscard]] auto ad_test::type_outer_use_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_use_d_ret{ double r {0.0}; double r_d {0.0}; -type_outer t_d {}; +type_outer_d t_d {}; type_outer t {}; - t_d.a = x_d; + t_d.a_d = x_d; t.a = x; - double temp_1_d {cpp2::move(t_d).a}; + double temp_1_d {cpp2::move(t_d).a_d}; double temp_1 {cpp2::move(t).a}; r_d = cpp2::move(temp_1_d) + y_d; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index adcccd359..e6f60d4a1 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -800,11 +800,11 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - t_d: type_outer = (); + t_d: type_outer_d = (); t: type_outer = (); - t_d.a = x_d; + t_d.a_d = x_d; t.a = x; - temp_1_d: double = t_d.a; + temp_1_d: double = t_d.a_d; temp_1: double = t.a; r_d = temp_1_d + y_d; r = temp_1 + y; diff --git a/source/reflect.h b/source/reflect.h index 59a78de82..28444661f 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -118,91 +118,91 @@ class autodiff_declaration_stack_item; class autodiff_context; -#line 4244 "reflect.h2" +#line 4261 "reflect.h2" class autodiff_handler_base; -#line 4258 "reflect.h2" +#line 4275 "reflect.h2" class autodiff_expression_handler; -#line 4708 "reflect.h2" +#line 4725 "reflect.h2" class autodiff_stmt_handler; -#line 4964 "reflect.h2" +#line 4981 "reflect.h2" class autodiff_declaration_handler; -#line 5200 "reflect.h2" +#line 5219 "reflect.h2" class expression_flags; -#line 5216 "reflect.h2" +#line 5235 "reflect.h2" class regex_token; -#line 5243 "reflect.h2" +#line 5262 "reflect.h2" class regex_token_check; -#line 5264 "reflect.h2" +#line 5283 "reflect.h2" class regex_token_code; -#line 5285 "reflect.h2" +#line 5304 "reflect.h2" class regex_token_empty; -#line 5303 "reflect.h2" +#line 5322 "reflect.h2" class regex_token_list; -#line 5355 "reflect.h2" +#line 5374 "reflect.h2" class parse_context_group_state; -#line 5416 "reflect.h2" +#line 5435 "reflect.h2" class parse_context_branch_reset_state; -#line 5459 "reflect.h2" +#line 5478 "reflect.h2" class parse_context; -#line 5860 "reflect.h2" +#line 5879 "reflect.h2" class generation_function_context; -#line 5878 "reflect.h2" +#line 5897 "reflect.h2" class generation_context; -#line 6077 "reflect.h2" +#line 6096 "reflect.h2" class alternative_token; -#line 6092 "reflect.h2" +#line 6111 "reflect.h2" class alternative_token_gen; -#line 6157 "reflect.h2" +#line 6176 "reflect.h2" class any_token; -#line 6174 "reflect.h2" +#line 6193 "reflect.h2" class atomic_group_token; -#line 6204 "reflect.h2" +#line 6223 "reflect.h2" class char_token; -#line 6319 "reflect.h2" +#line 6338 "reflect.h2" class class_token; -#line 6543 "reflect.h2" +#line 6562 "reflect.h2" class group_ref_token; -#line 6680 "reflect.h2" +#line 6699 "reflect.h2" class group_token; -#line 7027 "reflect.h2" +#line 7046 "reflect.h2" class lookahead_lookbehind_token; -#line 7122 "reflect.h2" +#line 7141 "reflect.h2" class range_token; -#line 7279 "reflect.h2" +#line 7298 "reflect.h2" class special_range_token; -#line 7365 "reflect.h2" +#line 7384 "reflect.h2" template class regex_generator; -#line 7622 "reflect.h2" +#line 7641 "reflect.h2" } } @@ -1743,54 +1743,59 @@ class autodiff_context { public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4099 "reflect.h2" +#line 4098 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4109 "reflect.h2" +#line 4116 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; using lookup_function_declaration_ret = std::vector; -#line 4132 "reflect.h2" +#line 4139 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; +using lookup_type_declaration_ret = std::vector; + + +#line 4149 "reflect.h2" + public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4142 "reflect.h2" +#line 4159 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4164 "reflect.h2" +#line 4181 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4172 "reflect.h2" +#line 4189 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4192 "reflect.h2" +#line 4209 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4202 "reflect.h2" +#line 4219 "reflect.h2" public: auto enter_function() & -> void; -#line 4206 "reflect.h2" +#line 4223 "reflect.h2" public: auto leave_function() & -> void; -#line 4209 "reflect.h2" +#line 4226 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4222 "reflect.h2" +#line 4239 "reflect.h2" public: auto pop_stack() & -> void; -#line 4237 "reflect.h2" +#line 4254 "reflect.h2" public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4242 "reflect.h2" +#line 4259 "reflect.h2" }; class autodiff_handler_base { @@ -1799,21 +1804,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4249 "reflect.h2" +#line 4266 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4253 "reflect.h2" +#line 4270 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4256 "reflect.h2" +#line 4273 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4262 "reflect.h2" +#line 4279 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1821,195 +1826,195 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4271 "reflect.h2" +#line 4288 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; -#line 4280 "reflect.h2" +#line 4297 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; -#line 4284 "reflect.h2" +#line 4301 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4290 "reflect.h2" +#line 4307 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; -#line 4294 "reflect.h2" +#line 4311 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4303 "reflect.h2" +#line 4320 "reflect.h2" public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4312 "reflect.h2" +#line 4329 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; -#line 4352 "reflect.h2" +#line 4369 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4472 "reflect.h2" +#line 4489 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4507 "reflect.h2" +#line 4524 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4511 "reflect.h2" +#line 4528 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4515 "reflect.h2" +#line 4532 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4519 "reflect.h2" +#line 4536 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4523 "reflect.h2" +#line 4540 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4527 "reflect.h2" +#line 4544 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4531 "reflect.h2" +#line 4548 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4535 "reflect.h2" +#line 4552 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4539 "reflect.h2" +#line 4556 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4543 "reflect.h2" +#line 4560 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4547 "reflect.h2" +#line 4564 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4551 "reflect.h2" +#line 4568 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4576 "reflect.h2" +#line 4593 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4631 "reflect.h2" +#line 4648 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4635 "reflect.h2" +#line 4652 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4640 "reflect.h2" +#line 4657 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4680 "reflect.h2" +#line 4697 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4706 "reflect.h2" +#line 4723 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4712 "reflect.h2" +#line 4729 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4721 "reflect.h2" +#line 4738 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4726 "reflect.h2" +#line 4743 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4731 "reflect.h2" +#line 4748 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4758 "reflect.h2" +#line 4775 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4763 "reflect.h2" +#line 4780 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4768 "reflect.h2" +#line 4785 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4773 "reflect.h2" +#line 4790 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4781 "reflect.h2" +#line 4798 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4798 "reflect.h2" +#line 4815 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4845 "reflect.h2" +#line 4862 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4856 "reflect.h2" +#line 4873 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4860 "reflect.h2" +#line 4877 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4873 "reflect.h2" +#line 4890 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4877 "reflect.h2" +#line 4894 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4881 "reflect.h2" +#line 4898 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4885 "reflect.h2" +#line 4902 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4889 "reflect.h2" +#line 4906 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4893 "reflect.h2" +#line 4910 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4897 "reflect.h2" +#line 4914 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4901 "reflect.h2" +#line 4918 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4905 "reflect.h2" +#line 4922 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4909 "reflect.h2" +#line 4926 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4913 "reflect.h2" +#line 4930 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4917 "reflect.h2" +#line 4934 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4921 "reflect.h2" +#line 4938 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4926 "reflect.h2" +#line 4943 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4958 "reflect.h2" +#line 4975 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4962 "reflect.h2" +#line 4979 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4968 "reflect.h2" +#line 4985 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2019,37 +2024,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4980 "reflect.h2" +#line 4997 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4985 "reflect.h2" +#line 5002 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5049 "reflect.h2" +#line 5066 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5075 "reflect.h2" +#line 5092 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5097 "reflect.h2" +#line 5116 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5102 "reflect.h2" +#line 5121 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5105 "reflect.h2" +#line 5124 "reflect.h2" }; -#line 5108 "reflect.h2" +#line 5127 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5196 "reflect.h2" +#line 5215 "reflect.h2" using error_func = std::function x)>; -#line 5200 "reflect.h2" +#line 5219 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2084,20 +2089,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5208 "reflect.h2" +#line 5227 "reflect.h2" }; -#line 5216 "reflect.h2" +#line 5235 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5224 "reflect.h2" +#line 5243 "reflect.h2" public: explicit regex_token(); -#line 5229 "reflect.h2" +#line 5248 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2109,103 +2114,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5235 "reflect.h2" +#line 5254 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5241 "reflect.h2" +#line 5260 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5247 "reflect.h2" +#line 5266 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5254 "reflect.h2" +#line 5273 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5258 "reflect.h2" +#line 5277 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5259 "reflect.h2" +#line 5278 "reflect.h2" }; -#line 5262 "reflect.h2" +#line 5281 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5268 "reflect.h2" +#line 5287 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5275 "reflect.h2" +#line 5294 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5279 "reflect.h2" +#line 5298 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5280 "reflect.h2" +#line 5299 "reflect.h2" }; -#line 5283 "reflect.h2" +#line 5302 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5289 "reflect.h2" +#line 5308 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5293 "reflect.h2" +#line 5312 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5297 "reflect.h2" +#line 5316 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5298 "reflect.h2" +#line 5317 "reflect.h2" }; -#line 5301 "reflect.h2" +#line 5320 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5307 "reflect.h2" +#line 5326 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5314 "reflect.h2" +#line 5333 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5320 "reflect.h2" +#line 5339 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5326 "reflect.h2" +#line 5345 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5334 "reflect.h2" +#line 5353 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2213,10 +2218,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5346 "reflect.h2" +#line 5365 "reflect.h2" }; -#line 5349 "reflect.h2" +#line 5368 "reflect.h2" // // Parse and generation context. // @@ -2232,33 +2237,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5369 "reflect.h2" +#line 5388 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5376 "reflect.h2" +#line 5395 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5388 "reflect.h2" +#line 5407 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5393 "reflect.h2" +#line 5412 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5397 "reflect.h2" +#line 5416 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5411 "reflect.h2" +#line 5430 "reflect.h2" }; -#line 5414 "reflect.h2" +#line 5433 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2271,25 +2276,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5432 "reflect.h2" +#line 5451 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5438 "reflect.h2" +#line 5457 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5445 "reflect.h2" +#line 5464 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5452 "reflect.h2" +#line 5471 "reflect.h2" }; -#line 5455 "reflect.h2" +#line 5474 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2305,7 +2310,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5471 "reflect.h2" +#line 5490 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2313,64 +2318,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5482 "reflect.h2" +#line 5501 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5495 "reflect.h2" +#line 5514 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5503 "reflect.h2" +#line 5522 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5507 "reflect.h2" +#line 5526 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5511 "reflect.h2" +#line 5530 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5523 "reflect.h2" +#line 5542 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5530 "reflect.h2" +#line 5549 "reflect.h2" public: auto next_alternative() & -> void; -#line 5536 "reflect.h2" +#line 5555 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5542 "reflect.h2" +#line 5561 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5546 "reflect.h2" +#line 5565 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5557 "reflect.h2" +#line 5576 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5561 "reflect.h2" +#line 5580 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5567 "reflect.h2" +#line 5586 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5571 "reflect.h2" +#line 5590 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5578 "reflect.h2" +#line 5597 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5589 "reflect.h2" +#line 5608 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2378,51 +2383,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5633 "reflect.h2" +#line 5652 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5645 "reflect.h2" +#line 5664 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5658 "reflect.h2" +#line 5677 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5681 "reflect.h2" +#line 5700 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5698 "reflect.h2" +#line 5717 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5719 "reflect.h2" +#line 5738 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5729 "reflect.h2" +#line 5748 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5733 "reflect.h2" +#line 5752 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5789 "reflect.h2" +#line 5808 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5828 "reflect.h2" +#line 5847 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5843 "reflect.h2" +#line 5862 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2434,10 +2439,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5854 "reflect.h2" +#line 5873 "reflect.h2" }; -#line 5857 "reflect.h2" +#line 5876 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2447,16 +2452,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5871 "reflect.h2" +#line 5890 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5874 "reflect.h2" +#line 5893 "reflect.h2" }; -#line 5877 "reflect.h2" +#line 5896 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2476,68 +2481,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5899 "reflect.h2" +#line 5918 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5905 "reflect.h2" +#line 5924 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5914 "reflect.h2" +#line 5933 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5925 "reflect.h2" +#line 5944 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5932 "reflect.h2" +#line 5951 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5952 "reflect.h2" +#line 5971 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5962 "reflect.h2" +#line 5981 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 5985 "reflect.h2" +#line 6004 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 5993 "reflect.h2" +#line 6012 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 5997 "reflect.h2" +#line 6016 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6003 "reflect.h2" +#line 6022 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6009 "reflect.h2" +#line 6028 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6019 "reflect.h2" +#line 6038 "reflect.h2" public: auto finish_context() & -> void; -#line 6027 "reflect.h2" +#line 6046 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6033 "reflect.h2" +#line 6052 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6037 "reflect.h2" +#line 6056 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6041 "reflect.h2" +#line 6060 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6065 "reflect.h2" +#line 6084 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2545,7 +2550,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6071 "reflect.h2" +#line 6090 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2565,27 +2570,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6090 "reflect.h2" +#line 6109 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6096 "reflect.h2" +#line 6115 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6103 "reflect.h2" +#line 6122 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6120 "reflect.h2" +#line 6139 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6127 "reflect.h2" +#line 6146 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6140 "reflect.h2" +#line 6159 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2593,19 +2598,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6152 "reflect.h2" +#line 6171 "reflect.h2" }; -#line 6155 "reflect.h2" +#line 6174 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6161 "reflect.h2" +#line 6180 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6165 "reflect.h2" +#line 6184 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2613,7 +2618,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6170 "reflect.h2" +#line 6189 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2621,17 +2626,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6178 "reflect.h2" +#line 6197 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6189 "reflect.h2" +#line 6208 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6197 "reflect.h2" +#line 6216 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2639,7 +2644,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6200 "reflect.h2" +#line 6219 "reflect.h2" }; // Regex syntax: a @@ -2647,34 +2652,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6208 "reflect.h2" +#line 6227 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6217 "reflect.h2" +#line 6236 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6223 "reflect.h2" +#line 6242 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6227 "reflect.h2" +#line 6246 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6250 "reflect.h2" +#line 6269 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6271 "reflect.h2" +#line 6290 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6289 "reflect.h2" +#line 6308 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6304 "reflect.h2" +#line 6323 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6310 "reflect.h2" +#line 6329 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2682,33 +2687,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6314 "reflect.h2" +#line 6333 "reflect.h2" }; -#line 6317 "reflect.h2" +#line 6336 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6323 "reflect.h2" +#line 6342 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6335 "reflect.h2" +#line 6354 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6461 "reflect.h2" +#line 6480 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6470 "reflect.h2" +#line 6489 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6475 "reflect.h2" +#line 6494 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2716,20 +2721,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6482 "reflect.h2" +#line 6501 "reflect.h2" }; -#line 6485 "reflect.h2" +#line 6504 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6526 "reflect.h2" +#line 6545 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6537 "reflect.h2" +#line 6556 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2739,20 +2744,20 @@ class class_token class group_ref_token : public regex_token { -#line 6547 "reflect.h2" +#line 6566 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6559 "reflect.h2" +#line 6578 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6660 "reflect.h2" +#line 6679 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6664 "reflect.h2" +#line 6683 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2760,10 +2765,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6667 "reflect.h2" +#line 6686 "reflect.h2" }; -#line 6670 "reflect.h2" +#line 6689 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2777,29 +2782,29 @@ class group_ref_token class group_token : public regex_token { -#line 6684 "reflect.h2" +#line 6703 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6706 "reflect.h2" +#line 6725 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6720 "reflect.h2" +#line 6739 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6879 "reflect.h2" +#line 6898 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6887 "reflect.h2" +#line 6906 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6905 "reflect.h2" +#line 6924 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6936 "reflect.h2" +#line 6955 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2808,25 +2813,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6943 "reflect.h2" +#line 6962 "reflect.h2" }; -#line 6946 "reflect.h2" +#line 6965 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 6987 "reflect.h2" +#line 7006 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7007 "reflect.h2" +#line 7026 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7023 "reflect.h2" +#line 7042 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2834,20 +2839,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7031 "reflect.h2" +#line 7050 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7040 "reflect.h2" +#line 7059 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7051 "reflect.h2" +#line 7070 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7058 "reflect.h2" +#line 7077 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2855,26 +2860,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7061 "reflect.h2" +#line 7080 "reflect.h2" }; -#line 7064 "reflect.h2" +#line 7083 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7092 "reflect.h2" +#line 7111 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7120 "reflect.h2" +#line 7139 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7126 "reflect.h2" +#line 7145 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2884,22 +2889,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7206 "reflect.h2" +#line 7225 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7218 "reflect.h2" +#line 7237 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7231 "reflect.h2" +#line 7250 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7250 "reflect.h2" +#line 7269 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7260 "reflect.h2" +#line 7279 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7271 "reflect.h2" +#line 7290 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2907,16 +2912,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7274 "reflect.h2" +#line 7293 "reflect.h2" }; -#line 7277 "reflect.h2" +#line 7296 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7283 "reflect.h2" +#line 7302 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2925,7 +2930,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7313 "reflect.h2" +#line 7332 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2934,14 +2939,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7335 "reflect.h2" +#line 7354 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7357 "reflect.h2" +#line 7376 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2962,24 +2967,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7380 "reflect.h2" +#line 7399 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7415 "reflect.h2" +#line 7434 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7429 "reflect.h2" +#line 7448 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7441 "reflect.h2" +#line 7460 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7496 "reflect.h2" +#line 7515 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2990,7 +2995,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7622 "reflect.h2" +#line 7641 "reflect.h2" } } @@ -7715,22 +7720,29 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return "temp_" + cpp2::to_string(temporary_count) + ""; } - // TODO: Have the proper type declaration here. -#line 4099 "reflect.h2" +#line 4098 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ + auto type_d {type}; + + if ("double" != type) { + auto type_decls {lookup_type_declaration(type)}; + if (!(CPP2_UFCS(empty)(type_decls))) { + // We found a cpp2 type declaration, mark it for differentiation. + add_for_differentiation(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(type_decls), 0)); - // TODO: Lookup if type is a known type and if it has AD values. - if (order == 1) { - return type; // Same type for now for order 1 + // Add the AD suffix to the type + type_d += suffix; + } } - return string_util::replace_all(type, "double", ad_type); + // Replace with AD type for the AD order. + return string_util::replace_all(cpp2::move(type_d), "double", ad_type); } -#line 4109 "reflect.h2" +#line 4116 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4110 "reflect.h2" +#line 4117 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7753,10 +7765,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4132 "reflect.h2" +#line 4139 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4133 "reflect.h2" +#line 4140 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7766,12 +7778,25 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4142 "reflect.h2" +#line 4149 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ + std::vector r {}; +#line 4150 "reflect.h2" + auto r_all {lookup_declaration(decl_name)}; + + for ( auto const& cur : cpp2::move(r_all) ) { + if (CPP2_UFCS(is_type)(cur)) { + CPP2_UFCS(push_back)(r, CPP2_UFCS(as_type)(cur)); + } + }return r; + } + +#line 4159 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4143 "reflect.h2" +#line 4160 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -7793,7 +7818,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4164 "reflect.h2" +#line 4181 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -7802,7 +7827,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4172 "reflect.h2" +#line 4189 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -7823,7 +7848,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4192 "reflect.h2" +#line 4209 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -7834,16 +7859,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4202 "reflect.h2" +#line 4219 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; } -#line 4206 "reflect.h2" +#line 4223 "reflect.h2" auto autodiff_context::leave_function() & -> void{ } -#line 4209 "reflect.h2" +#line 4226 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -7857,7 +7882,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4222 "reflect.h2" +#line 4239 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -7873,42 +7898,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4237 "reflect.h2" +#line 4254 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4249 "reflect.h2" +#line 4266 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4251 "reflect.h2" +#line 4268 "reflect.h2" } -#line 4249 "reflect.h2" +#line 4266 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4251 "reflect.h2" +#line 4268 "reflect.h2" } -#line 4253 "reflect.h2" +#line 4270 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4267 "reflect.h2" +#line 4284 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4269 "reflect.h2" +#line 4286 "reflect.h2" } -#line 4271 "reflect.h2" +#line 4288 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -7918,34 +7943,34 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4280 "reflect.h2" +#line 4297 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4284 "reflect.h2" +#line 4301 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } -#line 4286 "reflect.h2" +#line 4303 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } -#line 4290 "reflect.h2" +#line 4307 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4294 "reflect.h2" +#line 4311 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4296 "reflect.h2" +#line 4313 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4298 "reflect.h2" +#line 4315 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4303 "reflect.h2" +#line 4320 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -7955,7 +7980,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return args; } -#line 4312 "reflect.h2" +#line 4329 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ if (CPP2_UFCS(is_identifier)(term)) { return CPP2_UFCS(to_string)(term); @@ -7996,7 +8021,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }} } -#line 4352 "reflect.h2" +#line 4369 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8004,7 +8029,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4358 "reflect.h2" +#line 4375 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8018,7 +8043,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4370 "reflect.h2" +#line 4387 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8041,7 +8066,7 @@ auto i{0}; { auto i{0}; -#line 4391 "reflect.h2" +#line 4408 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8052,7 +8077,7 @@ auto i{0}; } else { object += "." + name; - object_d += "." + cpp2::move(name); + object_d += "." + cpp2::move(name) + (*cpp2::impl::assert_not_null(ctx)).suffix; } } else {if (CPP2_UFCS(get_op)(term) == "(") { @@ -8066,7 +8091,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4414 "reflect.h2" +#line 4431 "reflect.h2" if (handle_special_function(object, cpp2::move(object_d), function_name, args)) { return ; } @@ -8125,7 +8150,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4472 "reflect.h2" +#line 4489 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8148,7 +8173,7 @@ auto i{0}; { auto i{1}; -#line 4493 "reflect.h2" +#line 4510 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); @@ -8158,69 +8183,69 @@ auto i{1}; } } -#line 4501 "reflect.h2" +#line 4518 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4507 "reflect.h2" +#line 4524 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4511 "reflect.h2" +#line 4528 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4515 "reflect.h2" +#line 4532 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4519 "reflect.h2" +#line 4536 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4523 "reflect.h2" +#line 4540 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4527 "reflect.h2" +#line 4544 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4531 "reflect.h2" +#line 4548 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4535 "reflect.h2" +#line 4552 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4539 "reflect.h2" +#line 4556 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4543 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4547 "reflect.h2" +#line 4564 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4551 "reflect.h2" +#line 4568 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8246,7 +8271,7 @@ auto i{1}; fwd_expr = cpp2::move(fwd); } -#line 4576 "reflect.h2" +#line 4593 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8285,7 +8310,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4615 "reflect.h2" +#line 4632 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8302,18 +8327,18 @@ auto i{1}; } } -#line 4631 "reflect.h2" +#line 4648 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4635 "reflect.h2" +#line 4652 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4640 "reflect.h2" +#line 4657 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8322,7 +8347,7 @@ auto i{1}; { auto i{0}; -#line 4647 "reflect.h2" +#line 4664 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8337,7 +8362,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4660 "reflect.h2" +#line 4677 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8345,20 +8370,20 @@ auto i{0}; // Member access auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; - std::string obj_name {CPP2_UFCS(to_string)(cpp2::move(primary))}; - std::string obj_name_d {obj_name + (*cpp2::impl::assert_not_null(ctx)).suffix}; - std::string obj_access {""}; + std::string obj_access {CPP2_UFCS(to_string)(cpp2::move(primary))}; + std::string obj_access_d {obj_access + (*cpp2::impl::assert_not_null(ctx)).suffix}; for ( auto const& term : cpp2::move(terms) ) { - obj_access += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)); + obj_access += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)); + obj_access_d += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)) + (*cpp2::impl::assert_not_null(ctx)).suffix; } - primal_expr = "" + cpp2::to_string(cpp2::move(obj_name)) + cpp2::to_string(obj_access) + ""; - fwd_expr = "" + cpp2::to_string(cpp2::move(obj_name_d)) + cpp2::to_string(cpp2::move(obj_access)) + ""; + primal_expr = cpp2::move(obj_access); + fwd_expr = cpp2::move(obj_access_d); } } -#line 4680 "reflect.h2" +#line 4697 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8386,26 +8411,26 @@ auto i{0}; }}}} } -#line 4716 "reflect.h2" +#line 4733 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4719 "reflect.h2" +#line 4736 "reflect.h2" } -#line 4721 "reflect.h2" +#line 4738 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4726 "reflect.h2" +#line 4743 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4731 "reflect.h2" +#line 4748 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8432,22 +8457,22 @@ auto i{0}; diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; } -#line 4758 "reflect.h2" +#line 4775 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4763 "reflect.h2" +#line 4780 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4768 "reflect.h2" +#line 4785 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4773 "reflect.h2" +#line 4790 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8455,7 +8480,7 @@ auto i{0}; diff += "}\n"; } -#line 4781 "reflect.h2" +#line 4798 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8472,7 +8497,7 @@ auto i{0}; } } -#line 4798 "reflect.h2" +#line 4815 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8519,7 +8544,7 @@ auto i{0}; }} } -#line 4845 "reflect.h2" +#line 4862 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8531,12 +8556,12 @@ auto i{0}; } } -#line 4856 "reflect.h2" +#line 4873 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4860 "reflect.h2" +#line 4877 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8550,73 +8575,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 4873 "reflect.h2" +#line 4890 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 4877 "reflect.h2" +#line 4894 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 4881 "reflect.h2" +#line 4898 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 4885 "reflect.h2" +#line 4902 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 4889 "reflect.h2" +#line 4906 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 4893 "reflect.h2" +#line 4910 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 4897 "reflect.h2" +#line 4914 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 4901 "reflect.h2" +#line 4918 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 4905 "reflect.h2" +#line 4922 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements.."); + CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 4909 "reflect.h2" +#line 4926 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4913 "reflect.h2" +#line 4930 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4917 "reflect.h2" +#line 4934 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4921 "reflect.h2" +#line 4938 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4926 "reflect.h2" +#line 4943 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8625,7 +8650,7 @@ auto i{0}; { auto i{0}; -#line 4933 "reflect.h2" +#line 4950 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8640,7 +8665,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4946 "reflect.h2" +#line 4963 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8653,27 +8678,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4958 "reflect.h2" +#line 4975 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4975 "reflect.h2" +#line 4992 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4978 "reflect.h2" +#line 4995 "reflect.h2" } -#line 4980 "reflect.h2" +#line 4997 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4985 "reflect.h2" +#line 5002 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8717,10 +8742,10 @@ auto i{0}; return ; } -#line 5029 "reflect.h2" +#line 5046 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5032 "reflect.h2" +#line 5049 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8737,7 +8762,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5049 "reflect.h2" +#line 5066 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -8763,7 +8788,7 @@ auto i{0}; diff = ""; } -#line 5075 "reflect.h2" +#line 5092 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -8771,7 +8796,6 @@ auto i{0}; for ( auto const& m : CPP2_UFCS(get_members)(t) ) - if ( CPP2_UFCS(is_function)(m)) { CPP2_UFCS(pre_traverse)(ad, m); } @@ -8782,20 +8806,23 @@ auto i{0}; diff = "" + cpp2::to_string(CPP2_UFCS(name)(t)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : type = {\n"; diff += "" + cpp2::to_string(cpp2::move(ad).diff_ad_type) + ""; diff += "}"; + + CPP2_UFCS(add_member)(decl, diff); + diff = ""; } } -#line 5097 "reflect.h2" +#line 5116 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5102 "reflect.h2" +#line 5121 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5108 "reflect.h2" +#line 5127 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8831,7 +8858,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5144 "reflect.h2" +#line 5163 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8960,7 +8987,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5182 "reflect.h2" +#line 5201 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -8976,11 +9003,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5198 "reflect.h2" +#line 5217 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5202 "reflect.h2" +#line 5221 "reflect.h2" // mod: i // mod: m // mod: s @@ -8988,116 +9015,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5211 "reflect.h2" +#line 5230 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5220 "reflect.h2" +#line 5239 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5222 "reflect.h2" +#line 5241 "reflect.h2" } -#line 5224 "reflect.h2" +#line 5243 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5226 "reflect.h2" +#line 5245 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5232 "reflect.h2" +#line 5251 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5233 "reflect.h2" +#line 5252 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5234 "reflect.h2" +#line 5253 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5249 "reflect.h2" +#line 5268 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5252 "reflect.h2" +#line 5271 "reflect.h2" } -#line 5254 "reflect.h2" +#line 5273 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5258 "reflect.h2" +#line 5277 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5270 "reflect.h2" +#line 5289 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5273 "reflect.h2" +#line 5292 "reflect.h2" } -#line 5275 "reflect.h2" +#line 5294 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5279 "reflect.h2" +#line 5298 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5289 "reflect.h2" +#line 5308 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5291 "reflect.h2" +#line 5310 "reflect.h2" } -#line 5293 "reflect.h2" +#line 5312 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5297 "reflect.h2" +#line 5316 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5309 "reflect.h2" +#line 5328 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5312 "reflect.h2" +#line 5331 "reflect.h2" } -#line 5314 "reflect.h2" +#line 5333 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5320 "reflect.h2" +#line 5339 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5326 "reflect.h2" +#line 5345 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9106,7 +9133,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5334 "reflect.h2" +#line 5353 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9122,7 +9149,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5362 "reflect.h2" +#line 5381 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9130,14 +9157,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5370 "reflect.h2" +#line 5389 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5377 "reflect.h2" +#line 5396 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9149,15 +9176,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5389 "reflect.h2" +#line 5408 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5394 "reflect.h2" +#line 5413 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5398 "reflect.h2" +#line 5417 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9178,7 +9205,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5424 "reflect.h2" +#line 5443 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9187,20 +9214,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5433 "reflect.h2" +#line 5452 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5439 "reflect.h2" +#line 5458 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5446 "reflect.h2" +#line 5465 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9215,16 +9242,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5476 "reflect.h2" +#line 5495 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5480 "reflect.h2" +#line 5499 "reflect.h2" } -#line 5486 "reflect.h2" +#line 5505 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9234,7 +9261,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5496 "reflect.h2" +#line 5515 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9242,17 +9269,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5503 "reflect.h2" +#line 5522 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5507 "reflect.h2" +#line 5526 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5514 "reflect.h2" +#line 5533 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9262,7 +9289,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5523 "reflect.h2" +#line 5542 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9270,24 +9297,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5530 "reflect.h2" +#line 5549 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5538 "reflect.h2" +#line 5557 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5542 "reflect.h2" +#line 5561 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5546 "reflect.h2" +#line 5565 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9299,22 +9326,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5557 "reflect.h2" +#line 5576 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5563 "reflect.h2" +#line 5582 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5567 "reflect.h2" +#line 5586 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5571 "reflect.h2" +#line 5590 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9322,7 +9349,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5578 "reflect.h2" +#line 5597 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9334,10 +9361,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5591 "reflect.h2" +#line 5610 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5594 "reflect.h2" +#line 5613 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9377,7 +9404,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5634 "reflect.h2" +#line 5653 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9389,14 +9416,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5645 "reflect.h2" +#line 5664 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5646 "reflect.h2" +#line 5665 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5647 "reflect.h2" +#line 5666 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5649 "reflect.h2" +#line 5668 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9406,10 +9433,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5658 "reflect.h2" +#line 5677 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5660 "reflect.h2" +#line 5679 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9431,14 +9458,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5681 "reflect.h2" +#line 5700 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5682 "reflect.h2" +#line 5701 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5683 "reflect.h2" +#line 5702 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5685 "reflect.h2" +#line 5704 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9452,7 +9479,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5698 "reflect.h2" +#line 5717 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9474,7 +9501,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5719 "reflect.h2" +#line 5738 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9485,12 +9512,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5729 "reflect.h2" +#line 5748 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5730 "reflect.h2" +#line 5749 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5735 "reflect.h2" +#line 5754 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9545,7 +9572,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5789 "reflect.h2" +#line 5808 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9585,7 +9612,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5828 "reflect.h2" +#line 5847 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9601,21 +9628,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5845 "reflect.h2" +#line 5864 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5846 "reflect.h2" +#line 5865 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5847 "reflect.h2" +#line 5866 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5849 "reflect.h2" +#line 5868 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5864 "reflect.h2" +#line 5883 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9623,7 +9650,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5871 "reflect.h2" +#line 5890 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9633,22 +9660,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5889 "reflect.h2" +#line 5908 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5894 "reflect.h2" +#line 5913 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5900 "reflect.h2" +#line 5919 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5906 "reflect.h2" +#line 5925 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9657,7 +9684,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5914 "reflect.h2" +#line 5933 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9669,7 +9696,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5925 "reflect.h2" +#line 5944 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9677,7 +9704,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5932 "reflect.h2" +#line 5951 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9698,7 +9725,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5953 "reflect.h2" +#line 5972 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9708,7 +9735,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5963 "reflect.h2" +#line 5982 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9731,33 +9758,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5987 "reflect.h2" +#line 6006 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 5993 "reflect.h2" +#line 6012 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 5997 "reflect.h2" +#line 6016 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6003 "reflect.h2" +#line 6022 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6011 "reflect.h2" +#line 6030 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9766,7 +9793,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6019 "reflect.h2" +#line 6038 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9775,22 +9802,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6029 "reflect.h2" +#line 6048 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6033 "reflect.h2" +#line 6052 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6037 "reflect.h2" +#line 6056 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6041 "reflect.h2" +#line 6060 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9814,18 +9841,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6066 "reflect.h2" +#line 6085 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6081 "reflect.h2" +#line 6100 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6083 "reflect.h2" +#line 6102 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9836,15 +9863,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6098 "reflect.h2" +#line 6117 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6101 "reflect.h2" +#line 6120 "reflect.h2" } -#line 6103 "reflect.h2" +#line 6122 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9862,7 +9889,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6120 "reflect.h2" +#line 6139 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9870,7 +9897,7 @@ generation_function_context::generation_function_context(){} } } -#line 6127 "reflect.h2" +#line 6146 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9884,7 +9911,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6140 "reflect.h2" +#line 6159 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9900,14 +9927,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6161 "reflect.h2" +#line 6180 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6163 "reflect.h2" +#line 6182 "reflect.h2" } -#line 6165 "reflect.h2" +#line 6184 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9916,11 +9943,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6180 "reflect.h2" +#line 6199 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6182 "reflect.h2" +#line 6201 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9928,7 +9955,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6189 "reflect.h2" +#line 6208 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9937,37 +9964,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6197 "reflect.h2" +#line 6216 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6211 "reflect.h2" +#line 6230 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6215 "reflect.h2" +#line 6234 "reflect.h2" } -#line 6217 "reflect.h2" +#line 6236 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6221 "reflect.h2" +#line 6240 "reflect.h2" } -#line 6223 "reflect.h2" +#line 6242 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6227 "reflect.h2" +#line 6246 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -9976,14 +10003,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6233 "reflect.h2" +#line 6252 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6238 "reflect.h2" +#line 6257 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -9996,7 +10023,7 @@ size_t i{0}; } } -#line 6250 "reflect.h2" +#line 6269 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10018,7 +10045,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6271 "reflect.h2" +#line 6290 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10037,7 +10064,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6289 "reflect.h2" +#line 6308 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10053,14 +10080,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6304 "reflect.h2" +#line 6323 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6310 "reflect.h2" +#line 6329 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10068,19 +10095,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6327 "reflect.h2" +#line 6346 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6328 "reflect.h2" +#line 6347 "reflect.h2" { -#line 6333 "reflect.h2" +#line 6352 "reflect.h2" } -#line 6336 "reflect.h2" +#line 6355 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10206,7 +10233,7 @@ size_t i{0}; ); } -#line 6461 "reflect.h2" +#line 6480 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10216,13 +10243,13 @@ size_t i{0}; ); } -#line 6470 "reflect.h2" +#line 6489 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6475 "reflect.h2" +#line 6494 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10233,12 +10260,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6487 "reflect.h2" +#line 6506 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6492 "reflect.h2" +#line 6511 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10272,7 +10299,7 @@ size_t i{0}; } -#line 6528 "reflect.h2" +#line 6547 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10281,19 +10308,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6551 "reflect.h2" +#line 6570 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6552 "reflect.h2" +#line 6571 "reflect.h2" { -#line 6557 "reflect.h2" +#line 6576 "reflect.h2" } -#line 6559 "reflect.h2" +#line 6578 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10395,19 +10422,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6660 "reflect.h2" +#line 6679 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6664 "reflect.h2" +#line 6683 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6688 "reflect.h2" +#line 6707 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10426,7 +10453,7 @@ size_t i{0}; return r; } -#line 6706 "reflect.h2" +#line 6725 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10441,7 +10468,7 @@ size_t i{0}; return r; } -#line 6720 "reflect.h2" +#line 6739 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10601,7 +10628,7 @@ size_t i{0}; } } -#line 6879 "reflect.h2" +#line 6898 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10610,7 +10637,7 @@ size_t i{0}; return r; } -#line 6887 "reflect.h2" +#line 6906 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10629,7 +10656,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6905 "reflect.h2" +#line 6924 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10661,7 +10688,7 @@ size_t i{0}; } } -#line 6936 "reflect.h2" +#line 6955 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10672,7 +10699,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6948 "reflect.h2" +#line 6967 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10711,7 +10738,7 @@ size_t i{0}; return r; } -#line 6989 "reflect.h2" +#line 7008 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10729,7 +10756,7 @@ size_t i{0}; }} } -#line 7009 "reflect.h2" +#line 7028 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10743,16 +10770,16 @@ size_t i{0}; } } -#line 7035 "reflect.h2" +#line 7054 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7038 "reflect.h2" +#line 7057 "reflect.h2" } -#line 7040 "reflect.h2" +#line 7059 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10764,7 +10791,7 @@ size_t i{0}; } } -#line 7051 "reflect.h2" +#line 7070 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10772,14 +10799,14 @@ size_t i{0}; return r; } -#line 7058 "reflect.h2" +#line 7077 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7066 "reflect.h2" +#line 7085 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10805,7 +10832,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7094 "reflect.h2" +#line 7113 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10831,11 +10858,11 @@ size_t i{0}; return r; } -#line 7131 "reflect.h2" +#line 7150 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7133 "reflect.h2" +#line 7152 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10909,7 +10936,7 @@ size_t i{0}; return nullptr; } -#line 7206 "reflect.h2" +#line 7225 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10922,7 +10949,7 @@ size_t i{0}; }} } -#line 7218 "reflect.h2" +#line 7237 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10936,7 +10963,7 @@ size_t i{0}; }} } -#line 7231 "reflect.h2" +#line 7250 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10956,7 +10983,7 @@ size_t i{0}; return r; } -#line 7250 "reflect.h2" +#line 7269 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10967,7 +10994,7 @@ size_t i{0}; return r; } -#line 7260 "reflect.h2" +#line 7279 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10979,14 +11006,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7271 "reflect.h2" +#line 7290 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7283 "reflect.h2" +#line 7302 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11010,7 +11037,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7307 "reflect.h2" +#line 7326 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11020,7 +11047,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7319 "reflect.h2" +#line 7338 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11036,7 +11063,7 @@ size_t i{0}; } } -#line 7339 "reflect.h2" +#line 7358 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11054,15 +11081,15 @@ size_t i{0}; }} } -#line 7375 "reflect.h2" +#line 7394 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7378 "reflect.h2" +#line 7397 "reflect.h2" } -#line 7380 "reflect.h2" +#line 7399 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11098,7 +11125,7 @@ size_t i{0}; return source; } -#line 7415 "reflect.h2" +#line 7434 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11114,7 +11141,7 @@ size_t i{0}; } } -#line 7431 "reflect.h2" +#line 7450 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11123,7 +11150,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11178,7 +11205,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7500 "reflect.h2" +#line 7519 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11300,7 +11327,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7622 "reflect.h2" +#line 7641 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index a7609091a..3565f4c15 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4095,15 +4095,22 @@ autodiff_context: type = { return "temp_(temporary_count)$"; } - // TODO: Have the proper type declaration here. get_ad_type: (inout this, type: std::string) -> std::string = { + type_d := type; - // TODO: Lookup if type is a known type and if it has AD values. - if order == 1 { - return type; // Same type for now for order 1 + if "double" != type { + type_decls := lookup_type_declaration(type); + if !type_decls.empty() { + // We found a cpp2 type declaration, mark it for differentiation. + add_for_differentiation(type_decls[0]); + + // Add the AD suffix to the type + type_d += suffix; + } } - return string_util::replace_all(type, "double", ad_type); + // Replace with AD type for the AD order. + return string_util::replace_all(type_d, "double", ad_type); } lookup_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { @@ -4139,6 +4146,16 @@ autodiff_context: type = { } } + lookup_type_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { + r_all := lookup_declaration(decl_name); + + for r_all do (cur) { + if cur.is_type() { + r.push_back(cur.as_type()); + } + } + } + lookup_special_function_handling: (this, func_name: std::string, n_args: int, is_member: bool) -> (m: bool, code_primal: std::string, code_fwd: std::string) = { lookup : autodiff_special_func = (func_name, n_args, is_member); @@ -4398,7 +4415,7 @@ autodiff_expression_handler: type = { } else { object += "." + name; - object_d += "." + name; + object_d += "." + name + ctx*.suffix; } } else if term.get_op() == "(" { @@ -4663,17 +4680,17 @@ autodiff_expression_handler: type = { else { // Member access - primary : = postfix.get_primary_expression(); - obj_name : std::string = primary.to_string(); - obj_name_d : std::string = obj_name + ctx*.suffix; - obj_access : std::string = ""; + primary : = postfix.get_primary_expression(); + obj_access : std::string = primary.to_string(); + obj_access_d : std::string = obj_access + ctx*.suffix; for terms do (term) { - obj_access += term.get_op() + term.get_id_expression().to_string(); + obj_access += term.get_op() + term.get_id_expression().to_string(); + obj_access_d += term.get_op() + term.get_id_expression().to_string() + ctx*.suffix; } - primal_expr = "(obj_name)$(obj_access)$"; - fwd_expr = "(obj_name_d)$(obj_access)$"; + primal_expr = obj_access; + fwd_expr = obj_access_d; } } @@ -4730,7 +4747,7 @@ autodiff_stmt_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { lhs : std::string = o.name(); - type : = o.type(); + type : = o.type(); ad_type : = ctx*.get_ad_type(type); @@ -4871,39 +4888,39 @@ autodiff_stmt_handler: type = { } traverse: (override inout this, binexpr: meta::logical_or_expression) = { - binexpr.error( "AD: Logical or expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Logical or expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::logical_and_expression) = { - binexpr.error( "AD: Logical and expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Logical and expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::bit_or_expression) = { - binexpr.error( "AD: Bit or expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Bit or expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::bit_xor_expression) = { - binexpr.error( "AD: Bit xor expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Bit xor expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::bit_and_expression) = { - binexpr.error( "AD: Bit and expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Bit and expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::equality_expression) = { - binexpr.error( "AD: Equality or expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Equality or expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::relational_expression) = { - binexpr.error( "AD: Relational expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Relational expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::compare_expression) = { - binexpr.error( "AD: Compare or expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Compare or expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::shift_expression) = { - binexpr.error( "AD: Shift or expressions are not yet handled as standalone statements.." ); + binexpr.error( "AD: Shift or expressions are not yet handled as standalone statements." ); } traverse: (override inout this, binexpr: meta::additive_expression) = { @@ -5079,7 +5096,6 @@ autodiff_declaration_handler: type = { for t.get_members() do (m) - if m.is_function() { ad.pre_traverse(m); } @@ -5090,6 +5106,9 @@ autodiff_declaration_handler: type = { diff = "(t.name())$(ctx*.suffix)$ : type = {\n"; diff += "(ad.diff_ad_type)$"; diff += "}"; + + decl.add_member(diff); + diff = ""; } } From dd704be17db12c2a72f5961d63f10af671f4088d Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 15:40:56 +0200 Subject: [PATCH 36/54] Handling of member function calls. First basic setup for declared variable lookup. --- .../pure2-autodiff-higher-order.cpp2 | 12 + regression-tests/pure2-autodiff.cpp2 | 12 + .../pure2-autodiff-higher-order.cpp.execution | 8 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../pure2-autodiff-higher-order.cpp | 254 +-- .../pure2-autodiff-higher-order.cpp2.output | 31 + .../test-results/pure2-autodiff.cpp | 256 +-- .../test-results/pure2-autodiff.cpp2.output | 31 + source/reflect.h | 1503 ++++++++++------- source/reflect.h2 | 212 ++- 10 files changed, 1436 insertions(+), 884 deletions(-) diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index 5d5c466e1..df3c85dee 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -9,6 +9,10 @@ func_outer: (x: double, y: double) -> (ret: double) = { type_outer: type = { public a: double = 0.0; + + add: (this, b: double) -> double = { + return a + b; + } } ad_test: @autodiff<"order=6"> @print type = { @@ -173,6 +177,13 @@ ad_test: @autodiff<"order=6"> @print type = { r = t.a + y; } + + type_outer_call: (x: double, y: double) -> (r: double) = { + t : type_outer = (); + t.a = x; + + r = t.add(y); + } } } @@ -220,4 +231,5 @@ main: () = { write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); + write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, y, y_d)); } diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 515a2aee1..eb970219f 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -6,6 +6,10 @@ func_outer: (x: double, y: double) -> (ret: double) = { type_outer: type = { public a: double = 0.0; + + add: (this, b: double) -> double = { + return a + b; + } } ad_test: @autodiff @print type = { @@ -170,6 +174,13 @@ ad_test: @autodiff @print type = { r = t.a + y; } + + type_outer_call: (x: double, y: double) -> (r: double) = { + t : type_outer = (); + t.a = x; + + r = t.add(y); + } } } @@ -217,6 +228,7 @@ main: () = { write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); + write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, y, y_d)); r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index c1add3ddc..24f986a67 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -214,3 +214,11 @@ diff(tye_outer.a + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000 d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(type_outer.add(y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 29dd754ff..d57a638b3 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -25,4 +25,5 @@ diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 90b7344f6..1e534df9e 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -18,10 +18,10 @@ class type_outer; class type_outer_d; -#line 14 "pure2-autodiff-higher-order.cpp2" +#line 18 "pure2-autodiff-higher-order.cpp2" class ad_test; -#line 177 "pure2-autodiff-higher-order.cpp2" +#line 188 "pure2-autodiff-higher-order.cpp2" } @@ -42,11 +42,19 @@ using func_outer_ret = double; #line 10 "pure2-autodiff-higher-order.cpp2" class type_outer { public: double a {0.0}; + + public: [[nodiscard]] auto add(cpp2::impl::in b) const& -> double; +struct add_d_ret { double r; cpp2::taylor r_d; }; + + + public: [[nodiscard]] auto add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in> b_d) const& -> add_d_ret; + public: type_outer() = default; public: type_outer(type_outer const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(type_outer const&) -> void = delete; -#line 12 "pure2-autodiff-higher-order.cpp2" + +#line 16 "pure2-autodiff-higher-order.cpp2" }; struct func_outer_d_ret { double ret; cpp2::taylor ret_d; }; @@ -61,146 +69,151 @@ public: cpp2::taylor a_d {}; }; -#line 14 "pure2-autodiff-higher-order.cpp2" +#line 18 "pure2-autodiff-higher-order.cpp2" class ad_test { using add_1_ret = double; -#line 16 "pure2-autodiff-higher-order.cpp2" +#line 20 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 20 "pure2-autodiff-higher-order.cpp2" +#line 24 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 24 "pure2-autodiff-higher-order.cpp2" +#line 28 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 28 "pure2-autodiff-higher-order.cpp2" +#line 32 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 32 "pure2-autodiff-higher-order.cpp2" +#line 36 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 36 "pure2-autodiff-higher-order.cpp2" +#line 40 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 40 "pure2-autodiff-higher-order.cpp2" +#line 44 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 44 "pure2-autodiff-higher-order.cpp2" +#line 48 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 48 "pure2-autodiff-higher-order.cpp2" +#line 52 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 52 "pure2-autodiff-higher-order.cpp2" +#line 56 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 56 "pure2-autodiff-higher-order.cpp2" +#line 60 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 60 "pure2-autodiff-higher-order.cpp2" +#line 64 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 64 "pure2-autodiff-higher-order.cpp2" +#line 68 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 68 "pure2-autodiff-higher-order.cpp2" +#line 72 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 72 "pure2-autodiff-higher-order.cpp2" +#line 76 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 76 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 80 "pure2-autodiff-higher-order.cpp2" +#line 84 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 88 "pure2-autodiff-higher-order.cpp2" +#line 92 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 97 "pure2-autodiff-higher-order.cpp2" +#line 101 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 101 "pure2-autodiff-higher-order.cpp2" +#line 105 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 107 "pure2-autodiff-higher-order.cpp2" +#line 111 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 115 "pure2-autodiff-higher-order.cpp2" +#line 119 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 122 "pure2-autodiff-higher-order.cpp2" +#line 126 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 129 "pure2-autodiff-higher-order.cpp2" +#line 133 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 136 "pure2-autodiff-higher-order.cpp2" +#line 140 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 145 "pure2-autodiff-higher-order.cpp2" +#line 149 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 156 "pure2-autodiff-higher-order.cpp2" +#line 160 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; using type_outer_use_ret = double; -#line 170 "pure2-autodiff-higher-order.cpp2" +#line 174 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; +using type_outer_call_ret = double; + + +#line 181 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -314,18 +327,22 @@ struct type_outer_use_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto type_outer_use_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_use_d_ret; +struct type_outer_call_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_call_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 176 "pure2-autodiff-higher-order.cpp2" +#line 187 "pure2-autodiff-higher-order.cpp2" }; } auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 188 "pure2-autodiff-higher-order.cpp2" +#line 199 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -342,131 +359,142 @@ namespace ad_name { ret.construct(x + y); return std::move(ret.value()); } -[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_d_ret{ +#line 13 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto type_outer::add(cpp2::impl::in b) const& -> double{ + return a + b; + } + + [[nodiscard]] auto type_outer::add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in> b_d) const& -> add_d_ret{ + double r {}; + cpp2::taylor r_d {};r_d = this_d.a_d + b_d; + r = a + b; + return { std::move(r), std::move(r_d) }; } + + [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_d_ret{ double ret {0.0}; cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; -ret = x + y; -return { std::move(ret), std::move(ret_d) }; -} + ret = x + y; + return { std::move(ret), std::move(ret_d) }; + } -#line 16 "pure2-autodiff-higher-order.cpp2" +#line 20 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 17 "pure2-autodiff-higher-order.cpp2" +#line 21 "pure2-autodiff-higher-order.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 20 "pure2-autodiff-higher-order.cpp2" +#line 24 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 21 "pure2-autodiff-higher-order.cpp2" +#line 25 "pure2-autodiff-higher-order.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 24 "pure2-autodiff-higher-order.cpp2" +#line 28 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 25 "pure2-autodiff-higher-order.cpp2" +#line 29 "pure2-autodiff-higher-order.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 28 "pure2-autodiff-higher-order.cpp2" +#line 32 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 29 "pure2-autodiff-higher-order.cpp2" +#line 33 "pure2-autodiff-higher-order.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 32 "pure2-autodiff-higher-order.cpp2" +#line 36 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 33 "pure2-autodiff-higher-order.cpp2" +#line 37 "pure2-autodiff-higher-order.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 36 "pure2-autodiff-higher-order.cpp2" +#line 40 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 37 "pure2-autodiff-higher-order.cpp2" +#line 41 "pure2-autodiff-higher-order.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 40 "pure2-autodiff-higher-order.cpp2" +#line 44 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 41 "pure2-autodiff-higher-order.cpp2" +#line 45 "pure2-autodiff-higher-order.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 44 "pure2-autodiff-higher-order.cpp2" +#line 48 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 45 "pure2-autodiff-higher-order.cpp2" +#line 49 "pure2-autodiff-higher-order.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 48 "pure2-autodiff-higher-order.cpp2" +#line 52 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 49 "pure2-autodiff-higher-order.cpp2" +#line 53 "pure2-autodiff-higher-order.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 52 "pure2-autodiff-higher-order.cpp2" +#line 56 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 53 "pure2-autodiff-higher-order.cpp2" +#line 57 "pure2-autodiff-higher-order.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 56 "pure2-autodiff-higher-order.cpp2" +#line 60 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 57 "pure2-autodiff-higher-order.cpp2" +#line 61 "pure2-autodiff-higher-order.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 60 "pure2-autodiff-higher-order.cpp2" +#line 64 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 61 "pure2-autodiff-higher-order.cpp2" +#line 65 "pure2-autodiff-higher-order.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 64 "pure2-autodiff-higher-order.cpp2" +#line 68 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 65 "pure2-autodiff-higher-order.cpp2" +#line 69 "pure2-autodiff-higher-order.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 68 "pure2-autodiff-higher-order.cpp2" +#line 72 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 69 "pure2-autodiff-higher-order.cpp2" +#line 73 "pure2-autodiff-higher-order.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 72 "pure2-autodiff-higher-order.cpp2" +#line 76 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 73 "pure2-autodiff-higher-order.cpp2" +#line 77 "pure2-autodiff-higher-order.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } -#line 76 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 77 "pure2-autodiff-higher-order.cpp2" +#line 81 "pure2-autodiff-higher-order.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 80 "pure2-autodiff-higher-order.cpp2" +#line 84 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 81 "pure2-autodiff-higher-order.cpp2" +#line 85 "pure2-autodiff-higher-order.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -474,10 +502,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 88 "pure2-autodiff-higher-order.cpp2" +#line 92 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 89 "pure2-autodiff-higher-order.cpp2" +#line 93 "pure2-autodiff-higher-order.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -486,24 +514,24 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 97 "pure2-autodiff-higher-order.cpp2" +#line 101 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 101 "pure2-autodiff-higher-order.cpp2" +#line 105 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 102 "pure2-autodiff-higher-order.cpp2" +#line 106 "pure2-autodiff-higher-order.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 107 "pure2-autodiff-higher-order.cpp2" +#line 111 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 108 "pure2-autodiff-higher-order.cpp2" +#line 112 "pure2-autodiff-higher-order.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -511,40 +539,40 @@ return { std::move(ret), std::move(ret_d) }; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 115 "pure2-autodiff-higher-order.cpp2" +#line 119 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 116 "pure2-autodiff-higher-order.cpp2" +#line 120 "pure2-autodiff-higher-order.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 122 "pure2-autodiff-higher-order.cpp2" +#line 126 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 123 "pure2-autodiff-higher-order.cpp2" +#line 127 "pure2-autodiff-higher-order.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 129 "pure2-autodiff-higher-order.cpp2" +#line 133 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 130 "pure2-autodiff-higher-order.cpp2" +#line 134 "pure2-autodiff-higher-order.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 136 "pure2-autodiff-higher-order.cpp2" +#line 140 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 137 "pure2-autodiff-higher-order.cpp2" +#line 141 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -553,10 +581,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 145 "pure2-autodiff-higher-order.cpp2" +#line 149 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 146 "pure2-autodiff-higher-order.cpp2" +#line 150 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -567,10 +595,10 @@ return { std::move(ret), std::move(ret_d) }; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 156 "pure2-autodiff-higher-order.cpp2" +#line 160 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 157 "pure2-autodiff-higher-order.cpp2" +#line 161 "pure2-autodiff-higher-order.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -584,16 +612,26 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 170 "pure2-autodiff-higher-order.cpp2" +#line 174 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ cpp2::impl::deferred_init r; -#line 171 "pure2-autodiff-higher-order.cpp2" +#line 175 "pure2-autodiff-higher-order.cpp2" type_outer t {}; t.a = x; r.construct(cpp2::move(t).a + y); return std::move(r.value()); } +#line 181 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret{ + cpp2::impl::deferred_init r; +#line 182 "pure2-autodiff-higher-order.cpp2" + type_outer t {}; + t.a = x; + + r.construct(CPP2_UFCS(add)(cpp2::move(t), y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ double r {0.0}; cpp2::taylor r_d {0.0};r_d = x_d + y_d; @@ -919,28 +957,43 @@ type_outer_d t_d {}; return { std::move(r), std::move(r_d) }; } -#line 177 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::type_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_call_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +type_outer_d t_d {}; + + type_outer t {}; + t_d.a_d = x_d; + t.a = x; + + auto temp_1 {CPP2_UFCS(add_d)(cpp2::move(t), cpp2::move(t_d), y, y_d)}; + r_d = temp_1.r_d; + r = cpp2::move(temp_1).r; + return { std::move(r), std::move(r_d) }; + } + +#line 188 "pure2-autodiff-higher-order.cpp2" } -#line 179 "pure2-autodiff-higher-order.cpp2" +#line 190 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 183 "pure2-autodiff-higher-order.cpp2" +#line 194 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 186 "pure2-autodiff-higher-order.cpp2" +#line 197 "pure2-autodiff-higher-order.cpp2" } -#line 188 "pure2-autodiff-higher-order.cpp2" +#line 199 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 191 "pure2-autodiff-higher-order.cpp2" +#line 202 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; @@ -972,6 +1025,7 @@ auto main() -> int{ write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); - write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); + write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(cpp2::move(x), cpp2::move(x_d), cpp2::move(y), cpp2::move(y_d))); } diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 6fcff530d..1f583c777 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -297,6 +297,17 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + type_outer_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: type_outer = (); + t.a = x; + r = t.add(y); + return; + } + add_1_d:( in x: double, in x_d: cpp2::taylor, @@ -810,6 +821,26 @@ ad_test:/* @autodiff<"order=6"> @print */ type = r = temp_1 + y; return; } + + type_outer_call_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + t_d: type_outer_d = (); + t: type_outer = (); + t_d.a_d = x_d; + t.a = x; + temp_1: _ = t.add_d(t_d, y, y_d); + r_d = temp_1.r_d; + r = temp_1.r; + return; + } } ok (all Cpp2, passes safety checks) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 1f556a032..e17b78012 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -15,10 +15,10 @@ class type_outer; class type_outer_d; -#line 11 "pure2-autodiff.cpp2" +#line 15 "pure2-autodiff.cpp2" class ad_test; -#line 174 "pure2-autodiff.cpp2" +#line 185 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -37,11 +37,19 @@ using func_outer_ret = double; #line 7 "pure2-autodiff.cpp2" class type_outer { public: double a {0.0}; + + public: [[nodiscard]] auto add(cpp2::impl::in b) const& -> double; +struct add_d_ret { double r; double r_d; }; + + + public: [[nodiscard]] auto add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in b_d) const& -> add_d_ret; + public: type_outer() = default; public: type_outer(type_outer const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(type_outer const&) -> void = delete; -#line 9 "pure2-autodiff.cpp2" + +#line 13 "pure2-autodiff.cpp2" }; struct func_outer_d_ret { double ret; double ret_d; }; @@ -56,146 +64,151 @@ public: double a_d {}; }; -#line 11 "pure2-autodiff.cpp2" +#line 15 "pure2-autodiff.cpp2" class ad_test { using add_1_ret = double; -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using func_ret = double; -#line 61 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 69 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 73 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 77 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 85 "pure2-autodiff.cpp2" +#line 89 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 94 "pure2-autodiff.cpp2" +#line 98 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 98 "pure2-autodiff.cpp2" +#line 102 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 104 "pure2-autodiff.cpp2" +#line 108 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 112 "pure2-autodiff.cpp2" +#line 116 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 119 "pure2-autodiff.cpp2" +#line 123 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 126 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 133 "pure2-autodiff.cpp2" +#line 137 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 142 "pure2-autodiff.cpp2" +#line 146 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 153 "pure2-autodiff.cpp2" +#line 157 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; using type_outer_use_ret = double; -#line 167 "pure2-autodiff.cpp2" +#line 171 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; +using type_outer_call_ret = double; + + +#line 178 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret; struct add_1_d_ret { double r; double r_d; }; @@ -309,19 +322,23 @@ struct type_outer_use_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto type_outer_use_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_use_d_ret; +struct type_outer_call_d_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_call_d_ret; + public: ad_test() = default; public: ad_test(ad_test const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test const&) -> void = delete; -#line 173 "pure2-autodiff.cpp2" +#line 184 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 177 "pure2-autodiff.cpp2" +#line 188 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -341,12 +358,12 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 180 "pure2-autodiff.cpp2" +#line 191 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 186 "pure2-autodiff.cpp2" +#line 197 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -361,131 +378,142 @@ namespace ad_name { ret.construct(x + y); return std::move(ret.value()); } -[[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret{ +#line 10 "pure2-autodiff.cpp2" + [[nodiscard]] auto type_outer::add(cpp2::impl::in b) const& -> double{ + return a + b; + } + + [[nodiscard]] auto type_outer::add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in b_d) const& -> add_d_ret{ + double r {}; + double r_d {};r_d = this_d.a_d + b_d; + r = a + b; + return { std::move(r), std::move(r_d) }; } + + [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret{ double ret {0.0}; double ret_d {0.0};ret_d = x_d + y_d; -ret = x + y; -return { std::move(ret), std::move(ret_d) }; -} + ret = x + y; + return { std::move(ret), std::move(ret_d) }; + } -#line 13 "pure2-autodiff.cpp2" +#line 17 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 14 "pure2-autodiff.cpp2" +#line 18 "pure2-autodiff.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 17 "pure2-autodiff.cpp2" +#line 21 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 18 "pure2-autodiff.cpp2" +#line 22 "pure2-autodiff.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 21 "pure2-autodiff.cpp2" +#line 25 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 22 "pure2-autodiff.cpp2" +#line 26 "pure2-autodiff.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 25 "pure2-autodiff.cpp2" +#line 29 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 26 "pure2-autodiff.cpp2" +#line 30 "pure2-autodiff.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 29 "pure2-autodiff.cpp2" +#line 33 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 30 "pure2-autodiff.cpp2" +#line 34 "pure2-autodiff.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 33 "pure2-autodiff.cpp2" +#line 37 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 34 "pure2-autodiff.cpp2" +#line 38 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 37 "pure2-autodiff.cpp2" +#line 41 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 38 "pure2-autodiff.cpp2" +#line 42 "pure2-autodiff.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 41 "pure2-autodiff.cpp2" +#line 45 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 42 "pure2-autodiff.cpp2" +#line 46 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 45 "pure2-autodiff.cpp2" +#line 49 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 46 "pure2-autodiff.cpp2" +#line 50 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 49 "pure2-autodiff.cpp2" +#line 53 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 50 "pure2-autodiff.cpp2" +#line 54 "pure2-autodiff.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 53 "pure2-autodiff.cpp2" +#line 57 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 54 "pure2-autodiff.cpp2" +#line 58 "pure2-autodiff.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 57 "pure2-autodiff.cpp2" +#line 61 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 58 "pure2-autodiff.cpp2" +#line 62 "pure2-autodiff.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 61 "pure2-autodiff.cpp2" +#line 65 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 62 "pure2-autodiff.cpp2" +#line 66 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 65 "pure2-autodiff.cpp2" +#line 69 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 66 "pure2-autodiff.cpp2" +#line 70 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 69 "pure2-autodiff.cpp2" +#line 73 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 70 "pure2-autodiff.cpp2" +#line 74 "pure2-autodiff.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } -#line 73 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 74 "pure2-autodiff.cpp2" +#line 78 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 77 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 78 "pure2-autodiff.cpp2" +#line 82 "pure2-autodiff.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -493,10 +521,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 85 "pure2-autodiff.cpp2" +#line 89 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 86 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -505,24 +533,24 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 94 "pure2-autodiff.cpp2" +#line 98 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 98 "pure2-autodiff.cpp2" +#line 102 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 99 "pure2-autodiff.cpp2" +#line 103 "pure2-autodiff.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 104 "pure2-autodiff.cpp2" +#line 108 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 105 "pure2-autodiff.cpp2" +#line 109 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -530,40 +558,40 @@ return { std::move(ret), std::move(ret_d) }; static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 112 "pure2-autodiff.cpp2" +#line 116 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 113 "pure2-autodiff.cpp2" +#line 117 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 119 "pure2-autodiff.cpp2" +#line 123 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 120 "pure2-autodiff.cpp2" +#line 124 "pure2-autodiff.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 126 "pure2-autodiff.cpp2" +#line 130 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 127 "pure2-autodiff.cpp2" +#line 131 "pure2-autodiff.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 133 "pure2-autodiff.cpp2" +#line 137 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 134 "pure2-autodiff.cpp2" +#line 138 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -572,10 +600,10 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 142 "pure2-autodiff.cpp2" +#line 146 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 143 "pure2-autodiff.cpp2" +#line 147 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -586,10 +614,10 @@ return { std::move(ret), std::move(ret_d) }; cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 153 "pure2-autodiff.cpp2" +#line 157 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 154 "pure2-autodiff.cpp2" +#line 158 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -603,16 +631,26 @@ return { std::move(ret), std::move(ret_d) }; }return std::move(r.value()); } -#line 167 "pure2-autodiff.cpp2" +#line 171 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ cpp2::impl::deferred_init r; -#line 168 "pure2-autodiff.cpp2" +#line 172 "pure2-autodiff.cpp2" type_outer t {}; t.a = x; r.construct(cpp2::move(t).a + y); return std::move(r.value()); } +#line 178 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret{ + cpp2::impl::deferred_init r; +#line 179 "pure2-autodiff.cpp2" + type_outer t {}; + t.a = x; + + r.construct(CPP2_UFCS(add)(cpp2::move(t), y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_d_ret{ double r {0.0}; double r_d {0.0};r_d = x_d + y_d; @@ -938,13 +976,28 @@ type_outer_d t_d {}; return { std::move(r), std::move(r_d) }; } -#line 174 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::type_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_call_d_ret{ + double r {0.0}; + double r_d {0.0}; +type_outer_d t_d {}; + + type_outer t {}; + t_d.a_d = x_d; + t.a = x; + + auto temp_1 {CPP2_UFCS(add_d)(cpp2::move(t), cpp2::move(t_d), y, y_d)}; + r_d = temp_1.r_d; + r = cpp2::move(temp_1).r; + return { std::move(r), std::move(r_d) }; + } + +#line 185 "pure2-autodiff.cpp2" } -#line 177 "pure2-autodiff.cpp2" +#line 188 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 178 "pure2-autodiff.cpp2" +#line 189 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -981,12 +1034,12 @@ double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 182 "pure2-autodiff.cpp2" +#line 193 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 186 "pure2-autodiff.cpp2" +#line 197 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -1020,7 +1073,8 @@ auto main() -> int{ write_output("while loop", x, x_d, y, y_d, ad_name::ad_test::while_loop_d(x, x_d, y, y_d)); write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); - write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); + write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); + write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); auto r_twice {ad_test_twice::mul_1_d_d2(x, x_d, cpp2::move(x_d), 0.0)}; std::cout << "2nd order diff of x*x at " + cpp2::to_string(cpp2::move(x)) + " = " + cpp2::to_string(cpp2::move(r_twice).r_d_d2) + "" << std::endl; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index e6f60d4a1..27e351b93 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -297,6 +297,17 @@ ad_test:/* @autodiff @print */ type = return; } + type_outer_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + t: type_outer = (); + t.a = x; + r = t.add(y); + return; + } + add_1_d:( in x: double, in x_d: double, @@ -810,6 +821,26 @@ ad_test:/* @autodiff @print */ type = r = temp_1 + y; return; } + + type_outer_call_d:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + t_d: type_outer_d = (); + t: type_outer = (); + t_d.a_d = x_d; + t.a = x; + temp_1: _ = t.add_d(t_d, y, y_d); + r_d = temp_1.r_d; + r = temp_1.r; + return; + } } diff --git a/source/reflect.h b/source/reflect.h index 28444661f..faffa2f3e 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -112,97 +112,100 @@ class simple_traverser; class autodiff_special_func; #line 3996 "reflect.h2" +class autodiff_declared_variable; + +#line 4012 "reflect.h2" class autodiff_declaration_stack_item; -#line 4019 "reflect.h2" +#line 4051 "reflect.h2" class autodiff_context; -#line 4261 "reflect.h2" +#line 4326 "reflect.h2" class autodiff_handler_base; -#line 4275 "reflect.h2" +#line 4340 "reflect.h2" class autodiff_expression_handler; -#line 4725 "reflect.h2" +#line 4836 "reflect.h2" class autodiff_stmt_handler; -#line 4981 "reflect.h2" +#line 5097 "reflect.h2" class autodiff_declaration_handler; -#line 5219 "reflect.h2" +#line 5353 "reflect.h2" class expression_flags; -#line 5235 "reflect.h2" +#line 5369 "reflect.h2" class regex_token; -#line 5262 "reflect.h2" +#line 5396 "reflect.h2" class regex_token_check; -#line 5283 "reflect.h2" +#line 5417 "reflect.h2" class regex_token_code; -#line 5304 "reflect.h2" +#line 5438 "reflect.h2" class regex_token_empty; -#line 5322 "reflect.h2" +#line 5456 "reflect.h2" class regex_token_list; -#line 5374 "reflect.h2" +#line 5508 "reflect.h2" class parse_context_group_state; -#line 5435 "reflect.h2" +#line 5569 "reflect.h2" class parse_context_branch_reset_state; -#line 5478 "reflect.h2" +#line 5612 "reflect.h2" class parse_context; -#line 5879 "reflect.h2" +#line 6013 "reflect.h2" class generation_function_context; -#line 5897 "reflect.h2" +#line 6031 "reflect.h2" class generation_context; -#line 6096 "reflect.h2" +#line 6230 "reflect.h2" class alternative_token; -#line 6111 "reflect.h2" +#line 6245 "reflect.h2" class alternative_token_gen; -#line 6176 "reflect.h2" +#line 6310 "reflect.h2" class any_token; -#line 6193 "reflect.h2" +#line 6327 "reflect.h2" class atomic_group_token; -#line 6223 "reflect.h2" +#line 6357 "reflect.h2" class char_token; -#line 6338 "reflect.h2" +#line 6472 "reflect.h2" class class_token; -#line 6562 "reflect.h2" +#line 6696 "reflect.h2" class group_ref_token; -#line 6699 "reflect.h2" +#line 6833 "reflect.h2" class group_token; -#line 7046 "reflect.h2" +#line 7180 "reflect.h2" class lookahead_lookbehind_token; -#line 7141 "reflect.h2" +#line 7275 "reflect.h2" class range_token; -#line 7298 "reflect.h2" +#line 7432 "reflect.h2" class special_range_token; -#line 7384 "reflect.h2" +#line 7518 "reflect.h2" template class regex_generator; -#line 7641 "reflect.h2" +#line 7775 "reflect.h2" } } @@ -1675,6 +1678,25 @@ class autodiff_special_func { #line 3994 "reflect.h2" }; +class autodiff_declared_variable { + public: std::string name {""}; + public: std::string decl {""}; + public: bool is_member {false}; + + public: explicit autodiff_declared_variable(); + + public: autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_member_); + +#line 4009 "reflect.h2" + public: autodiff_declared_variable(autodiff_declared_variable const& that); +#line 4009 "reflect.h2" + public: auto operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& ; +#line 4009 "reflect.h2" + public: autodiff_declared_variable(autodiff_declared_variable&& that) noexcept; +#line 4009 "reflect.h2" + public: auto operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& ; +}; + class autodiff_declaration_stack_item { public: std::string full_name; public: meta::type_or_namespace_declaration decl; @@ -1682,23 +1704,31 @@ class autodiff_declaration_stack_item { public: std::vector diff_request {}; public: std::vector diff_done {}; + public: std::vector> declared_variables_stack {1}; + public: autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_); using lookup_declaration_ret = std::vector; -#line 4008 "reflect.h2" +#line 4026 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; +struct lookup_variable_declaration_ret { bool found; autodiff_declared_variable r; }; + + + +#line 4036 "reflect.h2" + public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret; public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4017 "reflect.h2" +#line 4049 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4029 "reflect.h2" +#line 4061 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, false, "sin(_a1_)", @@ -1723,79 +1753,90 @@ class autodiff_context { "_o_.push_back(_a1_);", "_od_.push_back(_ad1_);")}; -#line 4054 "reflect.h2" +#line 4086 "reflect.h2" public: std::string suffix {"_d"}; private: int order {1}; -#line 4058 "reflect.h2" +#line 4090 "reflect.h2" public: std::string ad_type {"double"}; public: std::map> declaration_map {}; public: std::vector declaration_stack {}; + public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member = false) & -> void; + +#line 4099 "reflect.h2" public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4080 "reflect.h2" +#line 4116 "reflect.h2" public: auto set_order(cpp2::impl::in new_order) & -> void; -#line 4091 "reflect.h2" +#line 4127 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4098 "reflect.h2" +#line 4134 "reflect.h2" public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4116 "reflect.h2" +#line 4152 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; + +#line 4175 "reflect.h2" + public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4139 "reflect.h2" +#line 4192 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; +using lookup_member_function_declaration_ret = std::vector; + + +#line 4202 "reflect.h2" + public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4149 "reflect.h2" +#line 4212 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4159 "reflect.h2" +#line 4222 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4181 "reflect.h2" +#line 4244 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4189 "reflect.h2" +#line 4252 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4209 "reflect.h2" +#line 4272 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4219 "reflect.h2" +#line 4282 "reflect.h2" public: auto enter_function() & -> void; -#line 4223 "reflect.h2" +#line 4287 "reflect.h2" public: auto leave_function() & -> void; -#line 4226 "reflect.h2" +#line 4291 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4239 "reflect.h2" +#line 4304 "reflect.h2" public: auto pop_stack() & -> void; -#line 4254 "reflect.h2" +#line 4319 "reflect.h2" public: auto finish() & -> void; public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4259 "reflect.h2" +#line 4324 "reflect.h2" }; class autodiff_handler_base { @@ -1804,21 +1845,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4266 "reflect.h2" +#line 4331 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4270 "reflect.h2" +#line 4335 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4273 "reflect.h2" +#line 4338 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4279 "reflect.h2" +#line 4344 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1826,195 +1867,205 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4288 "reflect.h2" +#line 4353 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; -#line 4297 "reflect.h2" +#line 4362 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; -#line 4301 "reflect.h2" +#line 4366 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4307 "reflect.h2" +#line 4372 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; -#line 4311 "reflect.h2" +#line 4376 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4320 "reflect.h2" - public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; +#line 4385 "reflect.h2" + public: class primal_fwd_name { + public: std::string primal {""}; + public: std::string fwd {""}; + public: primal_fwd_name(auto&& primal_, auto&& fwd_) +CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; +public: primal_fwd_name(); + +#line 4388 "reflect.h2" + }; + + public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4329 "reflect.h2" - public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> std::string; +#line 4399 "reflect.h2" + public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_name; -#line 4369 "reflect.h2" +#line 4450 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4489 "reflect.h2" - public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; +#line 4594 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4524 "reflect.h2" +#line 4629 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4528 "reflect.h2" +#line 4633 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4532 "reflect.h2" +#line 4637 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4536 "reflect.h2" +#line 4641 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4540 "reflect.h2" +#line 4645 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4544 "reflect.h2" +#line 4649 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4548 "reflect.h2" +#line 4653 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4552 "reflect.h2" +#line 4657 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4556 "reflect.h2" +#line 4661 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4560 "reflect.h2" +#line 4665 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4564 "reflect.h2" +#line 4669 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4568 "reflect.h2" +#line 4673 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4593 "reflect.h2" +#line 4697 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4648 "reflect.h2" +#line 4754 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4652 "reflect.h2" +#line 4758 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4657 "reflect.h2" +#line 4763 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4697 "reflect.h2" +#line 4803 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4723 "reflect.h2" +#line 4834 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4729 "reflect.h2" +#line 4840 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4738 "reflect.h2" +#line 4849 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4743 "reflect.h2" +#line 4854 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4748 "reflect.h2" +#line 4859 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4775 "reflect.h2" +#line 4888 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4780 "reflect.h2" +#line 4893 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4785 "reflect.h2" +#line 4898 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4790 "reflect.h2" +#line 4903 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4798 "reflect.h2" +#line 4911 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4815 "reflect.h2" +#line 4928 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4862 "reflect.h2" +#line 4978 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4873 "reflect.h2" +#line 4989 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4877 "reflect.h2" +#line 4993 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4890 "reflect.h2" +#line 5006 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4894 "reflect.h2" +#line 5010 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4898 "reflect.h2" +#line 5014 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4902 "reflect.h2" +#line 5018 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4906 "reflect.h2" +#line 5022 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4910 "reflect.h2" +#line 5026 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4914 "reflect.h2" +#line 5030 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4918 "reflect.h2" +#line 5034 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4922 "reflect.h2" +#line 5038 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4926 "reflect.h2" +#line 5042 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4930 "reflect.h2" +#line 5046 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4934 "reflect.h2" +#line 5050 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4938 "reflect.h2" +#line 5054 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4943 "reflect.h2" +#line 5059 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4975 "reflect.h2" +#line 5091 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 4979 "reflect.h2" +#line 5095 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 4985 "reflect.h2" +#line 5101 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2024,37 +2075,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 4997 "reflect.h2" +#line 5113 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5002 "reflect.h2" +#line 5118 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5066 "reflect.h2" +#line 5198 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5092 "reflect.h2" +#line 5226 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5116 "reflect.h2" +#line 5250 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5121 "reflect.h2" +#line 5255 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5124 "reflect.h2" +#line 5258 "reflect.h2" }; -#line 5127 "reflect.h2" +#line 5261 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5215 "reflect.h2" +#line 5349 "reflect.h2" using error_func = std::function x)>; -#line 5219 "reflect.h2" +#line 5353 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2089,20 +2140,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5227 "reflect.h2" +#line 5361 "reflect.h2" }; -#line 5235 "reflect.h2" +#line 5369 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5243 "reflect.h2" +#line 5377 "reflect.h2" public: explicit regex_token(); -#line 5248 "reflect.h2" +#line 5382 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2114,103 +2165,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5254 "reflect.h2" +#line 5388 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5260 "reflect.h2" +#line 5394 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5266 "reflect.h2" +#line 5400 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5273 "reflect.h2" +#line 5407 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5277 "reflect.h2" +#line 5411 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5278 "reflect.h2" +#line 5412 "reflect.h2" }; -#line 5281 "reflect.h2" +#line 5415 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5287 "reflect.h2" +#line 5421 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5294 "reflect.h2" +#line 5428 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5298 "reflect.h2" +#line 5432 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5299 "reflect.h2" +#line 5433 "reflect.h2" }; -#line 5302 "reflect.h2" +#line 5436 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5308 "reflect.h2" +#line 5442 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5312 "reflect.h2" +#line 5446 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5316 "reflect.h2" +#line 5450 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5317 "reflect.h2" +#line 5451 "reflect.h2" }; -#line 5320 "reflect.h2" +#line 5454 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5326 "reflect.h2" +#line 5460 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5333 "reflect.h2" +#line 5467 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5339 "reflect.h2" +#line 5473 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5345 "reflect.h2" +#line 5479 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5353 "reflect.h2" +#line 5487 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2218,10 +2269,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5365 "reflect.h2" +#line 5499 "reflect.h2" }; -#line 5368 "reflect.h2" +#line 5502 "reflect.h2" // // Parse and generation context. // @@ -2237,33 +2288,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5388 "reflect.h2" +#line 5522 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5395 "reflect.h2" +#line 5529 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5407 "reflect.h2" +#line 5541 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5412 "reflect.h2" +#line 5546 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5416 "reflect.h2" +#line 5550 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5430 "reflect.h2" +#line 5564 "reflect.h2" }; -#line 5433 "reflect.h2" +#line 5567 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2276,25 +2327,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5451 "reflect.h2" +#line 5585 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5457 "reflect.h2" +#line 5591 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5464 "reflect.h2" +#line 5598 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5471 "reflect.h2" +#line 5605 "reflect.h2" }; -#line 5474 "reflect.h2" +#line 5608 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2310,7 +2361,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5490 "reflect.h2" +#line 5624 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2318,64 +2369,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5501 "reflect.h2" +#line 5635 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5514 "reflect.h2" +#line 5648 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5522 "reflect.h2" +#line 5656 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5526 "reflect.h2" +#line 5660 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5530 "reflect.h2" +#line 5664 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5542 "reflect.h2" +#line 5676 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5549 "reflect.h2" +#line 5683 "reflect.h2" public: auto next_alternative() & -> void; -#line 5555 "reflect.h2" +#line 5689 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5561 "reflect.h2" +#line 5695 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5565 "reflect.h2" +#line 5699 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5576 "reflect.h2" +#line 5710 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5580 "reflect.h2" +#line 5714 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5586 "reflect.h2" +#line 5720 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5590 "reflect.h2" +#line 5724 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5597 "reflect.h2" +#line 5731 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5608 "reflect.h2" +#line 5742 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2383,51 +2434,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5652 "reflect.h2" +#line 5786 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5664 "reflect.h2" +#line 5798 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5677 "reflect.h2" +#line 5811 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5700 "reflect.h2" +#line 5834 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5717 "reflect.h2" +#line 5851 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5738 "reflect.h2" +#line 5872 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5748 "reflect.h2" +#line 5882 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5752 "reflect.h2" +#line 5886 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5808 "reflect.h2" +#line 5942 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5847 "reflect.h2" +#line 5981 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5862 "reflect.h2" +#line 5996 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2439,10 +2490,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 5873 "reflect.h2" +#line 6007 "reflect.h2" }; -#line 5876 "reflect.h2" +#line 6010 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2452,16 +2503,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 5890 "reflect.h2" +#line 6024 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 5893 "reflect.h2" +#line 6027 "reflect.h2" }; -#line 5896 "reflect.h2" +#line 6030 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2481,68 +2532,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 5918 "reflect.h2" +#line 6052 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 5924 "reflect.h2" +#line 6058 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 5933 "reflect.h2" +#line 6067 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 5944 "reflect.h2" +#line 6078 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 5951 "reflect.h2" +#line 6085 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 5971 "reflect.h2" +#line 6105 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 5981 "reflect.h2" +#line 6115 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6004 "reflect.h2" +#line 6138 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6012 "reflect.h2" +#line 6146 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6016 "reflect.h2" +#line 6150 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6022 "reflect.h2" +#line 6156 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6028 "reflect.h2" +#line 6162 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6038 "reflect.h2" +#line 6172 "reflect.h2" public: auto finish_context() & -> void; -#line 6046 "reflect.h2" +#line 6180 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6052 "reflect.h2" +#line 6186 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6056 "reflect.h2" +#line 6190 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6060 "reflect.h2" +#line 6194 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6084 "reflect.h2" +#line 6218 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2550,7 +2601,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6090 "reflect.h2" +#line 6224 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2570,27 +2621,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6109 "reflect.h2" +#line 6243 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6115 "reflect.h2" +#line 6249 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6122 "reflect.h2" +#line 6256 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6139 "reflect.h2" +#line 6273 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6146 "reflect.h2" +#line 6280 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6159 "reflect.h2" +#line 6293 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2598,19 +2649,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6171 "reflect.h2" +#line 6305 "reflect.h2" }; -#line 6174 "reflect.h2" +#line 6308 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6180 "reflect.h2" +#line 6314 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6184 "reflect.h2" +#line 6318 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2618,7 +2669,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6189 "reflect.h2" +#line 6323 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2626,17 +2677,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6197 "reflect.h2" +#line 6331 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6208 "reflect.h2" +#line 6342 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6216 "reflect.h2" +#line 6350 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2644,7 +2695,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6219 "reflect.h2" +#line 6353 "reflect.h2" }; // Regex syntax: a @@ -2652,34 +2703,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6227 "reflect.h2" +#line 6361 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6236 "reflect.h2" +#line 6370 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6242 "reflect.h2" +#line 6376 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6246 "reflect.h2" +#line 6380 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6269 "reflect.h2" +#line 6403 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6290 "reflect.h2" +#line 6424 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6308 "reflect.h2" +#line 6442 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6323 "reflect.h2" +#line 6457 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6329 "reflect.h2" +#line 6463 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2687,33 +2738,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6333 "reflect.h2" +#line 6467 "reflect.h2" }; -#line 6336 "reflect.h2" +#line 6470 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6342 "reflect.h2" +#line 6476 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6354 "reflect.h2" +#line 6488 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6480 "reflect.h2" +#line 6614 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6489 "reflect.h2" +#line 6623 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6494 "reflect.h2" +#line 6628 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2721,20 +2772,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6501 "reflect.h2" +#line 6635 "reflect.h2" }; -#line 6504 "reflect.h2" +#line 6638 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6545 "reflect.h2" +#line 6679 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6556 "reflect.h2" +#line 6690 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2744,20 +2795,20 @@ class class_token class group_ref_token : public regex_token { -#line 6566 "reflect.h2" +#line 6700 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6578 "reflect.h2" +#line 6712 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6679 "reflect.h2" +#line 6813 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6683 "reflect.h2" +#line 6817 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2765,10 +2816,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6686 "reflect.h2" +#line 6820 "reflect.h2" }; -#line 6689 "reflect.h2" +#line 6823 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2782,29 +2833,29 @@ class group_ref_token class group_token : public regex_token { -#line 6703 "reflect.h2" +#line 6837 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6725 "reflect.h2" +#line 6859 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6739 "reflect.h2" +#line 6873 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6898 "reflect.h2" +#line 7032 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6906 "reflect.h2" +#line 7040 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 6924 "reflect.h2" +#line 7058 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6955 "reflect.h2" +#line 7089 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2813,25 +2864,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 6962 "reflect.h2" +#line 7096 "reflect.h2" }; -#line 6965 "reflect.h2" +#line 7099 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7006 "reflect.h2" +#line 7140 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7026 "reflect.h2" +#line 7160 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7042 "reflect.h2" +#line 7176 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2839,20 +2890,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7050 "reflect.h2" +#line 7184 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7059 "reflect.h2" +#line 7193 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7070 "reflect.h2" +#line 7204 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7077 "reflect.h2" +#line 7211 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2860,26 +2911,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7080 "reflect.h2" +#line 7214 "reflect.h2" }; -#line 7083 "reflect.h2" +#line 7217 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7111 "reflect.h2" +#line 7245 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7139 "reflect.h2" +#line 7273 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7145 "reflect.h2" +#line 7279 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2889,22 +2940,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7225 "reflect.h2" +#line 7359 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7237 "reflect.h2" +#line 7371 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7250 "reflect.h2" +#line 7384 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7269 "reflect.h2" +#line 7403 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7279 "reflect.h2" +#line 7413 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7290 "reflect.h2" +#line 7424 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2912,16 +2963,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7293 "reflect.h2" +#line 7427 "reflect.h2" }; -#line 7296 "reflect.h2" +#line 7430 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7302 "reflect.h2" +#line 7436 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2930,7 +2981,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7332 "reflect.h2" +#line 7466 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2939,14 +2990,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7354 "reflect.h2" +#line 7488 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7376 "reflect.h2" +#line 7510 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -2967,24 +3018,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7399 "reflect.h2" +#line 7533 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7434 "reflect.h2" +#line 7568 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7448 "reflect.h2" +#line 7582 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7460 "reflect.h2" +#line 7594 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7515 "reflect.h2" +#line 7649 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -2995,7 +3046,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7641 "reflect.h2" +#line 7775 "reflect.h2" } } @@ -7623,21 +7674,59 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in return name == o.name && n_args == o.n_args && is_member == o.is_member; } -#line 3997 "reflect.h2" - // namespace + type name +#line 3998 "reflect.h2" + // TODO: Maybe use variant here. + +#line 4001 "reflect.h2" + autodiff_declared_variable::autodiff_declared_variable(){} #line 4003 "reflect.h2" + autodiff_declared_variable::autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_member_) + : name{ name_ } + , decl{ decl_ } + , is_member{ is_member_ }{ + +#line 4007 "reflect.h2" + } + +#line 4009 "reflect.h2" + autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable const& that) + : name{ that.name } + , decl{ that.decl } + , is_member{ that.is_member }{} +#line 4009 "reflect.h2" + auto autodiff_declared_variable::operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& { + name = that.name; + decl = that.decl; + is_member = that.is_member; + return *this; } +#line 4009 "reflect.h2" + autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable&& that) noexcept + : name{ std::move(that).name } + , decl{ std::move(that).decl } + , is_member{ std::move(that).is_member }{} +#line 4009 "reflect.h2" + auto autodiff_declared_variable::operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& { + name = std::move(that).name; + decl = std::move(that).decl; + is_member = std::move(that).is_member; + return *this; } + +#line 4013 "reflect.h2" + // namespace + type name + +#line 4021 "reflect.h2" autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) : full_name{ full_name_ } , decl{ decl_ }{ -#line 4006 "reflect.h2" +#line 4024 "reflect.h2" } -#line 4008 "reflect.h2" +#line 4026 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 4009 "reflect.h2" +#line 4027 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -7647,18 +7736,36 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return r; } +#line 4036 "reflect.h2" + [[nodiscard]] auto autodiff_declaration_stack_item::lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret{ + bool found {false}; + autodiff_declared_variable r {}; +#line 4037 "reflect.h2" + for ( auto const& cur_context : std::ranges::views::reverse(declared_variables_stack) ) { + for ( auto const& cur : cur_context ) { + if (cur.name == decl_name) { + found = true; + r = cur; + return { std::move(found), std::move(r) }; + } + } + }return { std::move(found), std::move(r) }; + } + autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that) : full_name{ that.full_name } , decl{ that.decl } , diff_request{ that.diff_request } - , diff_done{ that.diff_done }{} + , diff_done{ that.diff_done } + , declared_variables_stack{ that.declared_variables_stack }{} autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept : full_name{ std::move(that).full_name } , decl{ std::move(that).decl } , diff_request{ std::move(that).diff_request } - , diff_done{ std::move(that).diff_done }{} + , diff_done{ std::move(that).diff_done } + , declared_variables_stack{ std::move(that).declared_variables_stack }{} -#line 4022 "reflect.h2" +#line 4054 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7669,19 +7776,24 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar /* is_member = */ -#line 4037 "reflect.h2" +#line 4069 "reflect.h2" /* is_member = */ -#line 4043 "reflect.h2" +#line 4075 "reflect.h2" /* is_member = */ -#line 4049 "reflect.h2" +#line 4081 "reflect.h2" /* is_member = */ -#line 4057 "reflect.h2" +#line 4089 "reflect.h2" // Members depending on order -#line 4063 "reflect.h2" +#line 4095 "reflect.h2" + auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member) & -> void{ + CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_member)); + } + +#line 4099 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -7699,7 +7811,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4080 "reflect.h2" +#line 4116 "reflect.h2" auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ order = new_order; @@ -7711,16 +7823,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4091 "reflect.h2" +#line 4127 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4093 "reflect.h2" +#line 4129 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4098 "reflect.h2" +#line 4134 "reflect.h2" [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -7739,10 +7851,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", ad_type); } -#line 4116 "reflect.h2" +#line 4152 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4117 "reflect.h2" +#line 4153 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7765,10 +7877,28 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4139 "reflect.h2" +#line 4175 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ + if (name == "_") { + return autodiff_declared_variable(name, "_", false); + } + + for ( auto const& cur_context : std::ranges::views::reverse(declaration_stack) ) { + auto r {CPP2_UFCS(lookup_variable_declaration)(cur_context, name)}; + if (r.found) { + return cpp2::move(r).r; + } + } + + CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Could not find declaration of variable with name `" + cpp2::to_string(name) + "`."); + + return autodiff_declared_variable(); + } + +#line 4192 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4140 "reflect.h2" +#line 4193 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7778,10 +7908,23 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4149 "reflect.h2" +#line 4202 "reflect.h2" + [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ + std::vector r {}; +#line 4203 "reflect.h2" + for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { + if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { + CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); + + // Do not break for overloads. <3 + } + }return r; + } + +#line 4212 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4150 "reflect.h2" +#line 4213 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7791,12 +7934,12 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4159 "reflect.h2" +#line 4222 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4160 "reflect.h2" +#line 4223 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -7818,7 +7961,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4181 "reflect.h2" +#line 4244 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -7827,7 +7970,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4189 "reflect.h2" +#line 4252 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -7848,7 +7991,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4209 "reflect.h2" +#line 4272 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -7859,16 +8002,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4219 "reflect.h2" +#line 4282 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; + CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4223 "reflect.h2" +#line 4287 "reflect.h2" auto autodiff_context::leave_function() & -> void{ + CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4226 "reflect.h2" +#line 4291 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -7882,7 +8027,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4239 "reflect.h2" +#line 4304 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -7898,42 +8043,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4254 "reflect.h2" +#line 4319 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4266 "reflect.h2" +#line 4331 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4268 "reflect.h2" +#line 4333 "reflect.h2" } -#line 4266 "reflect.h2" +#line 4331 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4268 "reflect.h2" +#line 4333 "reflect.h2" } -#line 4270 "reflect.h2" +#line 4335 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4284 "reflect.h2" +#line 4349 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4286 "reflect.h2" +#line 4351 "reflect.h2" } -#line 4288 "reflect.h2" +#line 4353 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -7943,36 +8088,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4297 "reflect.h2" +#line 4362 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4301 "reflect.h2" +#line 4366 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } -#line 4303 "reflect.h2" +#line 4368 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } -#line 4307 "reflect.h2" +#line 4372 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4311 "reflect.h2" +#line 4376 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4313 "reflect.h2" +#line 4378 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4315 "reflect.h2" +#line 4380 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4320 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ - std::vector args {}; + autodiff_expression_handler::primal_fwd_name::primal_fwd_name(auto&& primal_, auto&& fwd_) +requires (std::is_convertible_v&> && std::is_convertible_v&>) + : primal{ CPP2_FORWARD(primal_) } + , fwd{ CPP2_FORWARD(fwd_) }{} +autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} + +#line 4390 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ + std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { CPP2_UFCS(push_back)(args, handle_expression_term(expr)); } @@ -7980,23 +8131,30 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return args; } -#line 4329 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> std::string{ +#line 4399 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_name{ if (CPP2_UFCS(is_identifier)(term)) { - return CPP2_UFCS(to_string)(term); + auto primal {CPP2_UFCS(to_string)(term)}; + auto fwd {primal + (*cpp2::impl::assert_not_null(ctx)).suffix}; + + auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal)}; + if (cpp2::move(decl).is_member) { + fwd = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "." + fwd; + } + return { cpp2::move(primal), cpp2::move(fwd) }; } else {if (CPP2_UFCS(is_expression_list)(term)) { auto exprs {term.as_expression_list().get_expressions()}; if (CPP2_UFCS(ssize)(exprs) != 1) { CPP2_UFCS(error)(term, "Can not handle multiple expressions. (term.to_string())"); - return "error"; + return { "error", "" }; } auto expr {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(exprs), 0)}; auto bin_expr {expr.as_assignment_expression()}; if (CPP2_UFCS(terms_size)(bin_expr) != 0) { CPP2_UFCS(error)(term, "Can not handle assign expr inside of expression. " + cpp2::to_string(CPP2_UFCS(to_string)(cpp2::move(expr))) + ""); - return "error"; + return { "error", "" }; } autodiff_expression_handler ad {ctx}; @@ -8005,7 +8163,9 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - return t; + primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).suffix}; // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + static_cast(cpp2::move(t)); + return r; } else { // Nothing special. A regular expression. @@ -8017,11 +8177,13 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - return t; + primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).suffix}; // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + static_cast(cpp2::move(t)); + return r; }} } -#line 4369 "reflect.h2" +#line 4450 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8029,7 +8191,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4375 "reflect.h2" +#line 4456 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8043,7 +8205,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4387 "reflect.h2" +#line 4468 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8052,7 +8214,7 @@ auto i{0}; std::string object {""}; std::string object_d {""}; std::string function_name {""}; - std::vector args {}; + std::vector args {}; auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; @@ -8066,7 +8228,7 @@ auto i{0}; { auto i{0}; -#line 4408 "reflect.h2" +#line 4489 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8091,14 +8253,14 @@ auto i{0}; } while (false); i += 1; } } -#line 4431 "reflect.h2" - if (handle_special_function(object, cpp2::move(object_d), function_name, args)) { +#line 4512 "reflect.h2" + if (handle_special_function(object, object_d, function_name, args)) { return ; } - // No special handling, currently only allow direct function calls - if (!(CPP2_UFCS(empty)(cpp2::move(object)))) { - CPP2_UFCS(error)(postfix, "AD: Can currently only handle direct function calls and no member function calls.: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + if (CPP2_UFCS(contains)(object, ".")) { + CPP2_UFCS(error)(postfix, "AD: can not handle nested member function calls: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); + return ; } // All arguments have now been handled. Form the function call @@ -8109,25 +8271,52 @@ auto i{0}; } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. + if (!(CPP2_UFCS(empty)(object))) {// Prepend object call + diff += "" + cpp2::to_string(object) + "."; + } diff += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "("; + if (!(CPP2_UFCS(empty)(object))) {// Add this_d argument. + diff += "" + cpp2::to_string(cpp2::move(object_d)) + ", "; + } for ( auto const& arg : cpp2::move(args) ) { - diff += "" + cpp2::to_string(arg) + ", " + cpp2::to_string(arg) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ","; + diff += "" + cpp2::to_string(arg.primal) + ", " + cpp2::to_string(arg.fwd) + ","; } diff += ");\n"; if (has_return) { - auto functions {CPP2_UFCS(lookup_function_declaration)((*cpp2::impl::assert_not_null(ctx)), function_name)}; - if (CPP2_UFCS(ssize)(functions) == 0) { - CPP2_UFCS(error)(postfix, "AD: Could not find function declaration for `" + cpp2::to_string(cpp2::move(function_name)) + "`.\n" - " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" - " If cpp function: please add a special handling for this function."); - } - else {if (CPP2_UFCS(ssize)(functions) != 1) { - CPP2_UFCS(error)(postfix, "AD: No handling for overload resultion is currently implemented."); - }} + std::vector functions {}; + if (!(CPP2_UFCS(empty)(object))) { + auto obj_decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), object)}; + auto obj_decl_types {CPP2_UFCS(lookup_type_declaration)((*cpp2::impl::assert_not_null(ctx)), obj_decl.decl)}; + + if (CPP2_UFCS(empty)(obj_decl_types)) { + CPP2_UFCS(error)(postfix, "AD: Could not find type declaration for `" + cpp2::to_string(cpp2::move(object)) + " with type " + cpp2::to_string(cpp2::move(obj_decl).decl) + "`.\n" + " If cpp2 object: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this member function."); + return ; + } + functions = CPP2_UFCS(lookup_member_function_declaration)((*cpp2::impl::assert_not_null(ctx)), CPP2_ASSERT_IN_BOUNDS_LITERAL(obj_decl_types, 0), cpp2::move(function_name)); + + CPP2_UFCS(add_for_differentiation)((*cpp2::impl::assert_not_null(ctx)), CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(obj_decl_types), 0));// TODO: Add more fine grained differentiation. + } + else { + functions = CPP2_UFCS(lookup_function_declaration)((*cpp2::impl::assert_not_null(ctx)), function_name); + if (CPP2_UFCS(ssize)(functions) == 0) { + CPP2_UFCS(error)(postfix, "AD: Could not find function declaration for `" + cpp2::to_string(cpp2::move(function_name)) + "`.\n" + " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this function."); + return ; + } + else {if (CPP2_UFCS(ssize)(functions) != 1) { + CPP2_UFCS(error)(postfix, "AD: No handling for overload resultion is currently implemented."); + return ; + }} + + CPP2_UFCS(add_for_differentiation)((*cpp2::impl::assert_not_null(ctx)), CPP2_ASSERT_IN_BOUNDS_LITERAL(functions, 0)); + } std::string ret_name {"r"}; // Default for regular return. - auto returns {CPP2_UFCS(get_returns)(CPP2_ASSERT_IN_BOUNDS_LITERAL(functions, 0))}; + auto returns {CPP2_UFCS(get_returns)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(functions), 0))}; if (!(CPP2_UFCS(empty)(returns))) { if (CPP2_UFCS(ssize)(returns) != 1) { CPP2_UFCS(error)(postfix, "AD: Expecting single return."); @@ -8142,16 +8331,13 @@ auto i{0}; primal_expr = "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + ""; fwd_expr = "" + cpp2::to_string(cpp2::move(ret_temp)) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + ""; - // TODO: check reverse order - - CPP2_UFCS(add_for_differentiation)((*cpp2::impl::assert_not_null(ctx)), CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(functions), 0)); } // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4489 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ +#line 4594 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8173,79 +8359,79 @@ auto i{0}; { auto i{1}; -#line 4510 "reflect.h2" +#line 4615 "reflect.h2" for ( auto const& arg : args ) { - code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg); - code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); + code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); + code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); - code_fwd = string_util::replace_all(code_fwd, "_a" + cpp2::to_string(i) + "_", arg); - code_fwd = string_util::replace_all(code_fwd, "_ad" + cpp2::to_string(i) + "_", arg + (*cpp2::impl::assert_not_null(ctx)).suffix); + code_fwd = string_util::replace_all(code_fwd, "_a" + cpp2::to_string(i) + "_", arg.primal); + code_fwd = string_util::replace_all(code_fwd, "_ad" + cpp2::to_string(i) + "_", arg.fwd); } } -#line 4518 "reflect.h2" +#line 4623 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4524 "reflect.h2" +#line 4629 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4528 "reflect.h2" +#line 4633 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4532 "reflect.h2" +#line 4637 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4536 "reflect.h2" +#line 4641 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4540 "reflect.h2" +#line 4645 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4544 "reflect.h2" +#line 4649 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4548 "reflect.h2" +#line 4653 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4552 "reflect.h2" +#line 4657 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4556 "reflect.h2" +#line 4661 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4560 "reflect.h2" +#line 4665 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4564 "reflect.h2" +#line 4669 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4568 "reflect.h2" +#line 4673 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8260,9 +8446,8 @@ auto i{1}; } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; - auto var_d {var + (*cpp2::impl::assert_not_null(ctx)).suffix}; - fwd += "" + cpp2::to_string(cpp2::move(var_d)) + ""; - primal += "" + cpp2::to_string(cpp2::move(var)) + ""; + fwd += var.fwd; + primal += cpp2::move(var).primal; first = false; } @@ -8271,17 +8456,19 @@ auto i{1}; fwd_expr = cpp2::move(fwd); } -#line 4593 "reflect.h2" +#line 4697 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; - auto arg_a {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; - auto arg_a_d {arg_a + (*cpp2::impl::assert_not_null(ctx)).suffix}; + auto var {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; + auto arg_a {var.primal}; + auto arg_a_d {var.fwd}; int i {1}; for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(terms)); i += 1 ) { - auto arg_b {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; - auto arg_b_d {arg_b + (*cpp2::impl::assert_not_null(ctx)).suffix}; + var = handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i))); + auto arg_b {var.primal}; + auto arg_b_d {var.fwd}; auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; @@ -8310,7 +8497,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4632 "reflect.h2" +#line 4738 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8327,18 +8514,18 @@ auto i{1}; } } -#line 4648 "reflect.h2" +#line 4754 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4652 "reflect.h2" +#line 4758 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); } -#line 4657 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8347,7 +8534,7 @@ auto i{1}; { auto i{0}; -#line 4664 "reflect.h2" +#line 4770 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8362,7 +8549,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4677 "reflect.h2" +#line 4783 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8383,12 +8570,17 @@ auto i{0}; } } -#line 4697 "reflect.h2" +#line 4803 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { primal_expr = CPP2_UFCS(to_string)(primary); fwd_expr = add_suffix_if_not_wildcard(primal_expr); + + auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal_expr)}; + if (cpp2::move(decl).is_member) { + fwd_expr = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "." + fwd_expr; + } } else {if (CPP2_UFCS(is_expression_list)(primary)) { if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { @@ -8411,26 +8603,26 @@ auto i{0}; }}}} } -#line 4733 "reflect.h2" +#line 4844 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4736 "reflect.h2" +#line 4847 "reflect.h2" } -#line 4738 "reflect.h2" +#line 4849 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4743 "reflect.h2" +#line 4854 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4748 "reflect.h2" +#line 4859 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8454,25 +8646,27 @@ auto i{0}; } } diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(cpp2::move(ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; - diff += "" + cpp2::to_string(cpp2::move(lhs)) + " : " + cpp2::to_string(cpp2::move(type)) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; + diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 4775 "reflect.h2" +#line 4888 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4780 "reflect.h2" +#line 4893 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4785 "reflect.h2" +#line 4898 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4790 "reflect.h2" +#line 4903 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8480,7 +8674,7 @@ auto i{0}; diff += "}\n"; } -#line 4798 "reflect.h2" +#line 4911 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8497,7 +8691,7 @@ auto i{0}; } } -#line 4815 "reflect.h2" +#line 4928 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8539,12 +8733,15 @@ auto i{0}; diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "");// TODO: Handle loop/compound context variable declarations. + pre_traverse(CPP2_UFCS(get_for_body)(stmt)); diff += "}\n"; }} } -#line 4862 "reflect.h2" +#line 4978 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8556,12 +8753,12 @@ auto i{0}; } } -#line 4873 "reflect.h2" +#line 4989 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4877 "reflect.h2" +#line 4993 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8575,73 +8772,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 4890 "reflect.h2" +#line 5006 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 4894 "reflect.h2" +#line 5010 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 4898 "reflect.h2" +#line 5014 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 4902 "reflect.h2" +#line 5018 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 4906 "reflect.h2" +#line 5022 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 4910 "reflect.h2" +#line 5026 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 4914 "reflect.h2" +#line 5030 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 4918 "reflect.h2" +#line 5034 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 4922 "reflect.h2" +#line 5038 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 4926 "reflect.h2" +#line 5042 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 4930 "reflect.h2" +#line 5046 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 4934 "reflect.h2" +#line 5050 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 4938 "reflect.h2" +#line 5054 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 4943 "reflect.h2" +#line 5059 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8650,7 +8847,7 @@ auto i{0}; { auto i{0}; -#line 4950 "reflect.h2" +#line 5066 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8665,7 +8862,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4963 "reflect.h2" +#line 5079 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8678,27 +8875,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 4975 "reflect.h2" +#line 5091 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 4992 "reflect.h2" +#line 5108 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 4995 "reflect.h2" +#line 5111 "reflect.h2" } -#line 4997 "reflect.h2" +#line 5113 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5002 "reflect.h2" +#line 5118 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8708,8 +8905,20 @@ auto i{0}; // a) Parameters for ( auto const& param : CPP2_UFCS(get_parameters)(f) ) { - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + ", "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + ", "; + std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; + + if ("this" == name) { + auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), std::string(CPP2_UFCS(name)(decl)))}; + diff += "" + cpp2::to_string(name) + ", "; + diff += "" + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(cpp2::move(ad_type)) + ", "; + } + else { + auto type {CPP2_UFCS(get_declaration)(param).type()}; + diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "; + diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "; + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type)); + } } diff += ") -> ("; @@ -8728,8 +8937,12 @@ auto i{0}; } else { for ( auto const& param : CPP2_UFCS(get_returns)(f) ) { - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param)))) + " = 0.0, "; + auto name {CPP2_UFCS(get_declaration)(param).name()}; + auto type {CPP2_UFCS(get_declaration)(param).type()}; + diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; + diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "; + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + ""); } } @@ -8742,10 +8955,10 @@ auto i{0}; return ; } -#line 5046 "reflect.h2" +#line 5178 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5049 "reflect.h2" +#line 5181 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8762,7 +8975,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5066 "reflect.h2" +#line 5198 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -8786,9 +8999,11 @@ auto i{0}; CPP2_UFCS(add_member)(decl, diff); } diff = ""; + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5092 "reflect.h2" +#line 5226 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -8812,17 +9027,17 @@ auto i{0}; } } -#line 5116 "reflect.h2" +#line 5250 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5121 "reflect.h2" +#line 5255 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5127 "reflect.h2" +#line 5261 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -8858,7 +9073,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5163 "reflect.h2" +#line 5297 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -8987,7 +9202,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5201 "reflect.h2" +#line 5335 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9003,11 +9218,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5217 "reflect.h2" +#line 5351 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5221 "reflect.h2" +#line 5355 "reflect.h2" // mod: i // mod: m // mod: s @@ -9015,116 +9230,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5230 "reflect.h2" +#line 5364 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5239 "reflect.h2" +#line 5373 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5241 "reflect.h2" +#line 5375 "reflect.h2" } -#line 5243 "reflect.h2" +#line 5377 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5245 "reflect.h2" +#line 5379 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5251 "reflect.h2" +#line 5385 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5252 "reflect.h2" +#line 5386 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5253 "reflect.h2" +#line 5387 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5268 "reflect.h2" +#line 5402 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5271 "reflect.h2" +#line 5405 "reflect.h2" } -#line 5273 "reflect.h2" +#line 5407 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5277 "reflect.h2" +#line 5411 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5289 "reflect.h2" +#line 5423 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5292 "reflect.h2" +#line 5426 "reflect.h2" } -#line 5294 "reflect.h2" +#line 5428 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5298 "reflect.h2" +#line 5432 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5308 "reflect.h2" +#line 5442 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5310 "reflect.h2" +#line 5444 "reflect.h2" } -#line 5312 "reflect.h2" +#line 5446 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5316 "reflect.h2" +#line 5450 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5328 "reflect.h2" +#line 5462 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5331 "reflect.h2" +#line 5465 "reflect.h2" } -#line 5333 "reflect.h2" +#line 5467 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5339 "reflect.h2" +#line 5473 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5345 "reflect.h2" +#line 5479 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9133,7 +9348,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5353 "reflect.h2" +#line 5487 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9149,7 +9364,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5381 "reflect.h2" +#line 5515 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9157,14 +9372,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5389 "reflect.h2" +#line 5523 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5396 "reflect.h2" +#line 5530 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9176,15 +9391,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5408 "reflect.h2" +#line 5542 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5413 "reflect.h2" +#line 5547 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5417 "reflect.h2" +#line 5551 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9205,7 +9420,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5443 "reflect.h2" +#line 5577 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9214,20 +9429,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5452 "reflect.h2" +#line 5586 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5458 "reflect.h2" +#line 5592 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5465 "reflect.h2" +#line 5599 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9242,16 +9457,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5495 "reflect.h2" +#line 5629 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5499 "reflect.h2" +#line 5633 "reflect.h2" } -#line 5505 "reflect.h2" +#line 5639 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9261,7 +9476,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5515 "reflect.h2" +#line 5649 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9269,17 +9484,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5522 "reflect.h2" +#line 5656 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5526 "reflect.h2" +#line 5660 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5533 "reflect.h2" +#line 5667 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9289,7 +9504,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5542 "reflect.h2" +#line 5676 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9297,24 +9512,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5549 "reflect.h2" +#line 5683 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5557 "reflect.h2" +#line 5691 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5561 "reflect.h2" +#line 5695 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5565 "reflect.h2" +#line 5699 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9326,22 +9541,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5576 "reflect.h2" +#line 5710 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5582 "reflect.h2" +#line 5716 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5586 "reflect.h2" +#line 5720 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5590 "reflect.h2" +#line 5724 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9349,7 +9564,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5597 "reflect.h2" +#line 5731 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9361,10 +9576,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5610 "reflect.h2" +#line 5744 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5613 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9404,7 +9619,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5653 "reflect.h2" +#line 5787 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9416,14 +9631,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5664 "reflect.h2" +#line 5798 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5665 "reflect.h2" +#line 5799 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5666 "reflect.h2" +#line 5800 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5668 "reflect.h2" +#line 5802 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9433,10 +9648,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5677 "reflect.h2" +#line 5811 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5679 "reflect.h2" +#line 5813 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9458,14 +9673,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5700 "reflect.h2" +#line 5834 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5701 "reflect.h2" +#line 5835 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5702 "reflect.h2" +#line 5836 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5704 "reflect.h2" +#line 5838 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9479,7 +9694,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5717 "reflect.h2" +#line 5851 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9501,7 +9716,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5738 "reflect.h2" +#line 5872 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9512,12 +9727,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5748 "reflect.h2" +#line 5882 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5749 "reflect.h2" +#line 5883 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5754 "reflect.h2" +#line 5888 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9572,7 +9787,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5808 "reflect.h2" +#line 5942 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9612,7 +9827,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5847 "reflect.h2" +#line 5981 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9628,21 +9843,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5864 "reflect.h2" +#line 5998 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5865 "reflect.h2" +#line 5999 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 5866 "reflect.h2" +#line 6000 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 5868 "reflect.h2" +#line 6002 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 5883 "reflect.h2" +#line 6017 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9650,7 +9865,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5890 "reflect.h2" +#line 6024 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9660,22 +9875,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 5908 "reflect.h2" +#line 6042 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 5913 "reflect.h2" +#line 6047 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 5919 "reflect.h2" +#line 6053 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 5925 "reflect.h2" +#line 6059 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9684,7 +9899,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 5933 "reflect.h2" +#line 6067 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9696,7 +9911,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 5944 "reflect.h2" +#line 6078 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9704,7 +9919,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 5951 "reflect.h2" +#line 6085 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9725,7 +9940,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 5972 "reflect.h2" +#line 6106 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9735,7 +9950,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 5982 "reflect.h2" +#line 6116 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9758,33 +9973,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6006 "reflect.h2" +#line 6140 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6012 "reflect.h2" +#line 6146 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6016 "reflect.h2" +#line 6150 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6022 "reflect.h2" +#line 6156 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6030 "reflect.h2" +#line 6164 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -9793,7 +10008,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6038 "reflect.h2" +#line 6172 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -9802,22 +10017,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6048 "reflect.h2" +#line 6182 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6052 "reflect.h2" +#line 6186 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6056 "reflect.h2" +#line 6190 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6060 "reflect.h2" +#line 6194 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -9841,18 +10056,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6085 "reflect.h2" +#line 6219 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6100 "reflect.h2" +#line 6234 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6102 "reflect.h2" +#line 6236 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -9863,15 +10078,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6117 "reflect.h2" +#line 6251 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6120 "reflect.h2" +#line 6254 "reflect.h2" } -#line 6122 "reflect.h2" +#line 6256 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -9889,7 +10104,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6139 "reflect.h2" +#line 6273 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -9897,7 +10112,7 @@ generation_function_context::generation_function_context(){} } } -#line 6146 "reflect.h2" +#line 6280 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -9911,7 +10126,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6159 "reflect.h2" +#line 6293 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -9927,14 +10142,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6180 "reflect.h2" +#line 6314 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6182 "reflect.h2" +#line 6316 "reflect.h2" } -#line 6184 "reflect.h2" +#line 6318 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -9943,11 +10158,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6199 "reflect.h2" +#line 6333 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6201 "reflect.h2" +#line 6335 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -9955,7 +10170,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6208 "reflect.h2" +#line 6342 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -9964,37 +10179,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6216 "reflect.h2" +#line 6350 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6230 "reflect.h2" +#line 6364 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6234 "reflect.h2" +#line 6368 "reflect.h2" } -#line 6236 "reflect.h2" +#line 6370 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6240 "reflect.h2" +#line 6374 "reflect.h2" } -#line 6242 "reflect.h2" +#line 6376 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6246 "reflect.h2" +#line 6380 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10003,14 +10218,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6252 "reflect.h2" +#line 6386 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6257 "reflect.h2" +#line 6391 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10023,7 +10238,7 @@ size_t i{0}; } } -#line 6269 "reflect.h2" +#line 6403 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10045,7 +10260,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6290 "reflect.h2" +#line 6424 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10064,7 +10279,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6308 "reflect.h2" +#line 6442 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10080,14 +10295,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6323 "reflect.h2" +#line 6457 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6329 "reflect.h2" +#line 6463 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10095,19 +10310,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6346 "reflect.h2" +#line 6480 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6347 "reflect.h2" +#line 6481 "reflect.h2" { -#line 6352 "reflect.h2" +#line 6486 "reflect.h2" } -#line 6355 "reflect.h2" +#line 6489 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10233,7 +10448,7 @@ size_t i{0}; ); } -#line 6480 "reflect.h2" +#line 6614 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10243,13 +10458,13 @@ size_t i{0}; ); } -#line 6489 "reflect.h2" +#line 6623 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6494 "reflect.h2" +#line 6628 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10260,12 +10475,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6506 "reflect.h2" +#line 6640 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6511 "reflect.h2" +#line 6645 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10299,7 +10514,7 @@ size_t i{0}; } -#line 6547 "reflect.h2" +#line 6681 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10308,19 +10523,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6570 "reflect.h2" +#line 6704 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6571 "reflect.h2" +#line 6705 "reflect.h2" { -#line 6576 "reflect.h2" +#line 6710 "reflect.h2" } -#line 6578 "reflect.h2" +#line 6712 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10422,19 +10637,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6679 "reflect.h2" +#line 6813 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6683 "reflect.h2" +#line 6817 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6707 "reflect.h2" +#line 6841 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10453,7 +10668,7 @@ size_t i{0}; return r; } -#line 6725 "reflect.h2" +#line 6859 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10468,7 +10683,7 @@ size_t i{0}; return r; } -#line 6739 "reflect.h2" +#line 6873 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10628,7 +10843,7 @@ size_t i{0}; } } -#line 6898 "reflect.h2" +#line 7032 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10637,7 +10852,7 @@ size_t i{0}; return r; } -#line 6906 "reflect.h2" +#line 7040 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10656,7 +10871,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 6924 "reflect.h2" +#line 7058 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10688,7 +10903,7 @@ size_t i{0}; } } -#line 6955 "reflect.h2" +#line 7089 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10699,7 +10914,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 6967 "reflect.h2" +#line 7101 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10738,7 +10953,7 @@ size_t i{0}; return r; } -#line 7008 "reflect.h2" +#line 7142 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10756,7 +10971,7 @@ size_t i{0}; }} } -#line 7028 "reflect.h2" +#line 7162 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10770,16 +10985,16 @@ size_t i{0}; } } -#line 7054 "reflect.h2" +#line 7188 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7057 "reflect.h2" +#line 7191 "reflect.h2" } -#line 7059 "reflect.h2" +#line 7193 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -10791,7 +11006,7 @@ size_t i{0}; } } -#line 7070 "reflect.h2" +#line 7204 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -10799,14 +11014,14 @@ size_t i{0}; return r; } -#line 7077 "reflect.h2" +#line 7211 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7085 "reflect.h2" +#line 7219 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10832,7 +11047,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7113 "reflect.h2" +#line 7247 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -10858,11 +11073,11 @@ size_t i{0}; return r; } -#line 7150 "reflect.h2" +#line 7284 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7152 "reflect.h2" +#line 7286 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -10936,7 +11151,7 @@ size_t i{0}; return nullptr; } -#line 7225 "reflect.h2" +#line 7359 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -10949,7 +11164,7 @@ size_t i{0}; }} } -#line 7237 "reflect.h2" +#line 7371 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -10963,7 +11178,7 @@ size_t i{0}; }} } -#line 7250 "reflect.h2" +#line 7384 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -10983,7 +11198,7 @@ size_t i{0}; return r; } -#line 7269 "reflect.h2" +#line 7403 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -10994,7 +11209,7 @@ size_t i{0}; return r; } -#line 7279 "reflect.h2" +#line 7413 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11006,14 +11221,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7290 "reflect.h2" +#line 7424 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7302 "reflect.h2" +#line 7436 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11037,7 +11252,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7326 "reflect.h2" +#line 7460 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11047,7 +11262,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7338 "reflect.h2" +#line 7472 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11063,7 +11278,7 @@ size_t i{0}; } } -#line 7358 "reflect.h2" +#line 7492 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11081,15 +11296,15 @@ size_t i{0}; }} } -#line 7394 "reflect.h2" +#line 7528 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7397 "reflect.h2" +#line 7531 "reflect.h2" } -#line 7399 "reflect.h2" +#line 7533 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11125,7 +11340,7 @@ size_t i{0}; return source; } -#line 7434 "reflect.h2" +#line 7568 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11141,7 +11356,7 @@ size_t i{0}; } } -#line 7450 "reflect.h2" +#line 7584 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11150,7 +11365,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11205,7 +11420,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7519 "reflect.h2" +#line 7653 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11327,7 +11542,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7641 "reflect.h2" +#line 7775 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 3565f4c15..b6ff60ab6 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -3993,6 +3993,22 @@ autodiff_special_func: type = { } } +autodiff_declared_variable: type = { + public name : std::string = ""; + public decl : std::string = ""; // TODO: Maybe use variant here. + public is_member: bool = false; + + operator=:(out this) = {} + + operator=:(out this, name_: std::string, decl_: std::string, is_member_: bool) = { + name = name_; + decl = decl_; + is_member = is_member_; + } + + operator=:(out this, that) = {} +} + autodiff_declaration_stack_item: @copy_constructible type = { public full_name: std::string; // namespace + type name public decl: meta::type_or_namespace_declaration; @@ -4000,6 +4016,8 @@ autodiff_declaration_stack_item: @copy_constructible type = { public diff_request: std::vector = (); public diff_done: std::vector = (); + public declared_variables_stack: std::vector> = (1); + operator=: (out this, full_name_: std::string, decl_: meta::type_or_namespace_declaration) = { full_name = full_name_; decl = decl_; @@ -4014,6 +4032,20 @@ autodiff_declaration_stack_item: @copy_constructible type = { } } } + + lookup_variable_declaration: (this, decl_name: std::string) -> (found: bool = false, r: autodiff_declared_variable = ()) = { + for std::ranges::views::reverse(declared_variables_stack) do (cur_context) { + for cur_context do (cur) { + if cur.name == decl_name { + found = true; + r = cur; + return; + } + } + } + } + + } autodiff_context: type = { @@ -4060,6 +4092,10 @@ autodiff_context: type = { public declaration_map : std::map> = (); public declaration_stack: std::vector = (); + add_variable_declaration: (inout this, name: std::string, type: std::string, is_member: bool = false) = { + declaration_stack.back().declared_variables_stack.back().push_back(autodiff_declared_variable(name, type, is_member)); + } + create_namespace_stack: (inout this, t: meta::type_or_namespace_declaration) = { if t.parent_is_nonglobal_namespace() { create_namespace_stack(t.get_parent().as_nonglobal_namespace()); @@ -4136,6 +4172,23 @@ autodiff_context: type = { return; } + lookup_variable_declaration: (inout this, name: std::string) -> autodiff_declared_variable = { + if name == "_" { + return autodiff_declared_variable(name, "_", false); + } + + for std::ranges::views::reverse(declaration_stack) do (cur_context) { + r := cur_context.lookup_variable_declaration(name); + if r.found { + return r.r; + } + } + + declaration_stack.back().decl.error("AD: Could not find declaration of variable with name `(name)$`."); + + return autodiff_declared_variable(); + } + lookup_function_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { r_all := lookup_declaration(decl_name); @@ -4146,6 +4199,16 @@ autodiff_context: type = { } } + lookup_member_function_declaration: (inout this, obj_type: meta::type_declaration, decl_name: std::string) -> (r : std::vector = ()) = { + for obj_type.get_members() do (cur) { + if cur.is_function() && cur.has_name() && decl_name == cur.name() { + r.push_back(cur.as_function()); + + // Do not break for overloads. <3 + } + } + } + lookup_type_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { r_all := lookup_declaration(decl_name); @@ -4218,9 +4281,11 @@ autodiff_context: type = { enter_function: (inout this) = { temporary_count = 0; + declaration_stack.back().declared_variables_stack.push_back(std::vector()); } leave_function: (inout this) = { + declaration_stack.back().declared_variables_stack.pop_back(); } push_stack: (inout this, decl: meta::type_or_namespace_declaration) = { @@ -4317,8 +4382,13 @@ autodiff_expression_handler: type = { - handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { - args : std::vector = (); + primal_fwd_name: @struct type = { + primal: std::string = ""; + fwd : std::string = ""; + } + + handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { + args : std::vector = (); for list.get_expressions() do (expr) { args.push_back(handle_expression_term(expr)); } @@ -4326,22 +4396,29 @@ autodiff_expression_handler: type = { return args; } - handle_expression_term :(inout this, term) -> std::string = { + handle_expression_term :(inout this, term) -> primal_fwd_name = { if term.is_identifier() { - return term.to_string(); + primal := term.to_string(); + fwd := primal + ctx*.suffix; + + decl := ctx*.lookup_variable_declaration(primal); + if decl.is_member { + fwd = "this(ctx*.suffix)$." + fwd; + } + return (primal, fwd); } else if term.is_expression_list() { exprs := term..as_expression_list()..get_expressions(); if exprs.ssize() != 1 { term.error("Can not handle multiple expressions. (term.to_string())"); - return "error"; + return ("error", ""); } expr := exprs[0]; bin_expr := expr..as_assignment_expression(); if bin_expr.terms_size() != 0 { term.error("Can not handle assign expr inside of expression. (expr.to_string())$"); - return "error"; + return ("error", ""); } ad : autodiff_expression_handler = (ctx); @@ -4350,7 +4427,9 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - return t; + r : primal_fwd_name = (t, t + ctx*.suffix); // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + _ = t; + return r; } else { // Nothing special. A regular expression. @@ -4362,7 +4441,9 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - return t; + r : primal_fwd_name = (t, t + ctx*.suffix); // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + _ = t; + return r; } } @@ -4392,7 +4473,7 @@ autodiff_expression_handler: type = { object : std::string = ""; object_d : std::string = ""; function_name : std::string = ""; - args : std::vector = (); + args : std::vector = (); primary := postfix.get_primary_expression(); @@ -4432,9 +4513,9 @@ autodiff_expression_handler: type = { return; } - // No special handling, currently only allow direct function calls - if !object.empty() { - postfix.error("AD: Can currently only handle direct function calls and no member function calls.: (postfix.to_string())$"); + if object.contains(".") { + postfix.error("AD: can not handle nested member function calls: (postfix.to_string())$"); + return; } // All arguments have now been handled. Form the function call @@ -4445,21 +4526,48 @@ autodiff_expression_handler: type = { } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. + if !object.empty() { // Prepend object call + diff += "(object)$."; + } diff += "(function_name)$(ctx*.suffix)$("; + if !object.empty() { // Add this_d argument. + diff += "(object_d)$, "; + } for args do (arg) { - diff += "(arg)$, (arg)$(ctx*.suffix)$,"; + diff += "(arg.primal)$, (arg.fwd)$,"; } diff += ");\n"; if has_return { - functions := ctx*.lookup_function_declaration(function_name); - if functions.ssize() == 0 { - postfix.error("AD: Could not find function declaration for `(function_name)$`.\n" - " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" - " If cpp function: please add a special handling for this function."); + functions : std::vector = (); + if !object.empty() { + obj_decl := ctx*.lookup_variable_declaration(object); + obj_decl_types := ctx*.lookup_type_declaration(obj_decl.decl); + + if obj_decl_types.empty() { + postfix.error("AD: Could not find type declaration for `(object)$ with type (obj_decl.decl)$`.\n" + " If cpp2 object: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this member function."); + return; + } + functions = ctx*.lookup_member_function_declaration(obj_decl_types[0], function_name); + + ctx*.add_for_differentiation(obj_decl_types[0]); // TODO: Add more fine grained differentiation. } - else if functions.ssize() != 1 { - postfix.error("AD: No handling for overload resultion is currently implemented."); + else { + functions = ctx*.lookup_function_declaration(function_name); + if functions.ssize() == 0 { + postfix.error("AD: Could not find function declaration for `(function_name)$`.\n" + " If cpp2 function: this is an alpha limitation, please declare it befor the current declaration.\n" + " If cpp function: please add a special handling for this function."); + return; + } + else if functions.ssize() != 1 { + postfix.error("AD: No handling for overload resultion is currently implemented."); + return; + } + + ctx*.add_for_differentiation(functions[0]); } ret_name : std::string = "r"; // Default for regular return. @@ -4478,15 +4586,12 @@ autodiff_expression_handler: type = { primal_expr = "(ret_temp)$.(ret_name)$"; fwd_expr = "(ret_temp)$.(ret_name_d)$"; - // TODO: check reverse order - - ctx*.add_for_differentiation(functions[0]); } // TODO: Add function to list of functions/objects for differentiation for the no return case. } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { + handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !object.empty()); @@ -4508,11 +4613,11 @@ autodiff_expression_handler: type = { (copy i := 1) for args do (arg) { - code_primal = string_util::replace_all(code_primal, "_a(i)$_", arg); - code_primal = string_util::replace_all(code_primal, "_ad(i)$_", arg + ctx*.suffix); + code_primal = string_util::replace_all(code_primal, "_a(i)$_", arg.primal); + code_primal = string_util::replace_all(code_primal, "_ad(i)$_", arg.fwd); - code_fwd = string_util::replace_all(code_fwd, "_a(i)$_", arg); - code_fwd = string_util::replace_all(code_fwd, "_ad(i)$_", arg + ctx*.suffix); + code_fwd = string_util::replace_all(code_fwd, "_a(i)$_", arg.primal); + code_fwd = string_util::replace_all(code_fwd, "_ad(i)$_", arg.fwd); } primal_expr = code_primal; @@ -4579,9 +4684,8 @@ autodiff_expression_handler: type = { } var := handle_expression_term(term.get_term()); - var_d := var + ctx*.suffix; - fwd += "(var_d)$"; - primal += "(var)$"; + fwd += var.fwd; + primal += var.primal; first = false; } @@ -4593,13 +4697,15 @@ autodiff_expression_handler: type = { traverse: (override inout this, binexpr: meta::multiplicative_expression) = { terms := binexpr.get_terms(); - arg_a := handle_expression_term(terms[0].get_term()); - arg_a_d := arg_a + ctx*.suffix; + var := handle_expression_term(terms[0].get_term()); + arg_a := var.primal; + arg_a_d := var.fwd; i : int = 1; while i < terms.ssize() next i += 1 { - arg_b := handle_expression_term(terms[i].get_term()); - arg_b_d := arg_b + ctx*.suffix; + var = handle_expression_term(terms[i].get_term()); + arg_b := var.primal; + arg_b_d := var.fwd; op := terms[i].get_op().to_string(); @@ -4699,6 +4805,11 @@ autodiff_expression_handler: type = { if primary.is_identifier() { primal_expr = primary.to_string(); fwd_expr = add_suffix_if_not_wildcard(primal_expr); + + decl := ctx*.lookup_variable_declaration(primal_expr); + if decl.is_member { + fwd_expr = "this(ctx*.suffix)$." + fwd_expr; + } } else if primary.is_expression_list() { if primary.as_expression_list().is_empty() { @@ -4769,6 +4880,8 @@ autodiff_stmt_handler: type = { } diff += "(lhs)$(ctx*.suffix)$ : (ad_type)$(fwd_init)$;\n"; diff += "(lhs)$ : (type)$(prim_init)$;\n"; + + ctx*.add_variable_declaration(lhs, type); } @@ -4853,6 +4966,9 @@ autodiff_stmt_handler: type = { diff += "(param_decl.name())$_d_iter++"; diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; diff += "((param_style)$ (param_decl.name())$(ctx*.suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; + + ctx*.add_variable_declaration("(param_decl.name())$", "(param_decl.type())$"); // TODO: Handle loop/compound context variable declarations. + pre_traverse(stmt.get_for_body()); diff += "}\n"; } @@ -5008,8 +5124,20 @@ autodiff_declaration_handler: type = { // a) Parameters for f.get_parameters() do (param) { - diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$, "; - diff += "(param.get_declaration().name())$(ctx*.suffix)$ : (ctx*.get_ad_type(param.get_declaration().type()))$, "; + name : std::string = param.get_declaration().name(); + + if "this" == name{ + ad_type := ctx*.get_ad_type(std::string(decl.name())); + diff += "(name)$, "; + diff += "(name)$(ctx*.suffix)$: (ad_type)$, "; + } + else { + type := param.get_declaration().type(); + diff += "(name)$ : (type)$, "; + diff += "(name)$(ctx*.suffix)$ : (ctx*.get_ad_type(type))$, "; + + ctx*.add_variable_declaration(name, type); + } } diff += ") -> ("; @@ -5028,8 +5156,12 @@ autodiff_declaration_handler: type = { } else { for f.get_returns() do (param) { - diff += "(param.get_declaration().name())$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(param.get_declaration().name())$(ctx*.suffix)$ : (ctx*.get_ad_type(param.get_declaration().type()))$ = 0.0, "; + name := param.get_declaration().name(); + type := param.get_declaration().type(); + diff += "(name)$ : (param.get_declaration().type())$ = 0.0, "; + diff += "(name)$(ctx*.suffix)$ : (ctx*.get_ad_type(type))$ = 0.0, "; + + ctx*.add_variable_declaration("(name)$", "(type)$"); } } @@ -5086,6 +5218,8 @@ autodiff_declaration_handler: type = { decl.add_member(diff); } diff = ""; + + ctx*.add_variable_declaration("(o.name())$", "(o.type())$", true); } From 211b4af372f2b65e3eab1f1b0dd0a49ed5cb7932 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 18 Aug 2025 16:01:41 +0200 Subject: [PATCH 37/54] Handling of prefix + and -. --- include/cpp2taylor.h2 | 17 + .../pure2-autodiff-higher-order.cpp2 | 10 + regression-tests/pure2-autodiff.cpp2 | 10 + .../pure2-autodiff-higher-order.cpp.execution | 16 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 + .../pure2-autodiff-higher-order.cpp | 172 ++-- .../pure2-autodiff-higher-order.cpp2.output | 52 + .../test-results/pure2-autodiff.cpp | 174 ++-- .../test-results/pure2-autodiff.cpp2.output | 52 + source/reflect.h | 955 +++++++++--------- source/reflect.h2 | 13 +- 11 files changed, 883 insertions(+), 590 deletions(-) diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index fc6432459..845af5d0f 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -63,6 +63,23 @@ taylor: type = { return sub(o, 0.0, 0.0); // Primal values are not required. } + // Overload for simple handling of prefix +. + operator+: (this) -> taylor = { + return this; + } + + // Overload for simple handling of prefix -. + operator-: (this) -> taylor = { + r: taylor = (); + + (copy k:= 1) + while k <= dim next k += 1 { + r.v[k - 1] = -v[k - 1]; + } + + return r; + } + add: (this, o: taylor, v0: R, o0: R) -> taylor = { r: taylor = (); diff --git a/regression-tests/pure2-autodiff-higher-order.cpp2 b/regression-tests/pure2-autodiff-higher-order.cpp2 index df3c85dee..cfa25c6bc 100644 --- a/regression-tests/pure2-autodiff-higher-order.cpp2 +++ b/regression-tests/pure2-autodiff-higher-order.cpp2 @@ -65,6 +65,14 @@ ad_test: @autodiff<"order=6"> @print type = { r = x + x * y; } + prefix_add: (x: double, y: double) -> (r: double) = { + r = +x + y; + } + + prefix_sub: (x: double, y: double) -> (r: double) = { + r = -x + y; + } + func: (x: double, y: double) -> (ret: double) = { ret = x + y; } @@ -216,6 +224,8 @@ main: () = { write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("+x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_add_d(x, x_d, y, y_d)); + write_output("-x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_sub_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index eb970219f..3dd253dde 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -62,6 +62,14 @@ ad_test: @autodiff @print type = { r = x + x * y; } + prefix_add: (x: double, y: double) -> (r: double) = { + r = +x + y; + } + + prefix_sub: (x: double, y: double) -> (r: double) = { + r = -x + y; + } + func: (x: double, y: double) -> (ret: double) = { ret = x + y; } @@ -213,6 +221,8 @@ main: () = { write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("+x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_add_d(x, x_d, y, y_d)); + write_output("-x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_sub_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution index 24f986a67..84a5f58de 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -94,6 +94,22 @@ diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0. d4 = 0.000000 d5 = 0.000000 d6 = 0.000000 +diff(+x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(-x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 1.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): r = 10.000000 d1 = 11.000000 diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index d57a638b3..b19924990 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -10,6 +10,8 @@ diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(+x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(-x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 1.000000, r_d = 1.000000) diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 1e534df9e..91b5ca793 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -21,7 +21,7 @@ class type_outer; #line 18 "pure2-autodiff-higher-order.cpp2" class ad_test; -#line 188 "pure2-autodiff-higher-order.cpp2" +#line 196 "pure2-autodiff-higher-order.cpp2" } @@ -131,88 +131,98 @@ using add_mul_ret = double; #line 64 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; -using func_ret = double; +using prefix_add_ret = double; #line 68 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto prefix_add(cpp2::impl::in x, cpp2::impl::in y) -> prefix_add_ret; +using prefix_sub_ret = double; + + +#line 72 "pure2-autodiff-higher-order.cpp2" + public: [[nodiscard]] static auto prefix_sub(cpp2::impl::in x, cpp2::impl::in y) -> prefix_sub_ret; +using func_ret = double; + + +#line 76 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 72 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 76 "pure2-autodiff-higher-order.cpp2" +#line 84 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 80 "pure2-autodiff-higher-order.cpp2" +#line 88 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 84 "pure2-autodiff-higher-order.cpp2" +#line 92 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 92 "pure2-autodiff-higher-order.cpp2" +#line 100 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 101 "pure2-autodiff-higher-order.cpp2" +#line 109 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 105 "pure2-autodiff-higher-order.cpp2" +#line 113 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 111 "pure2-autodiff-higher-order.cpp2" +#line 119 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 119 "pure2-autodiff-higher-order.cpp2" +#line 127 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 126 "pure2-autodiff-higher-order.cpp2" +#line 134 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 133 "pure2-autodiff-higher-order.cpp2" +#line 141 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 140 "pure2-autodiff-higher-order.cpp2" +#line 148 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 149 "pure2-autodiff-higher-order.cpp2" +#line 157 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 160 "pure2-autodiff-higher-order.cpp2" +#line 168 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; using type_outer_use_ret = double; -#line 174 "pure2-autodiff-higher-order.cpp2" +#line 182 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; using type_outer_call_ret = double; -#line 181 "pure2-autodiff-higher-order.cpp2" +#line 189 "pure2-autodiff-higher-order.cpp2" public: [[nodiscard]] static auto type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret; struct add_1_d_ret { double r; cpp2::taylor r_d; }; @@ -263,6 +273,14 @@ struct add_mul_d_ret { double r; cpp2::taylor r_d; }; public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret; +struct prefix_add_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto prefix_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_add_d_ret; + +struct prefix_sub_d_ret { double r; cpp2::taylor r_d; }; + +public: [[nodiscard]] static auto prefix_sub_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_sub_d_ret; + struct func_d_ret { double ret; cpp2::taylor ret_d; }; public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret; @@ -336,13 +354,13 @@ public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cp public: auto operator=(ad_test const&) -> void = delete; -#line 187 "pure2-autodiff-higher-order.cpp2" +#line 195 "pure2-autodiff-higher-order.cpp2" }; } auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 199 "pure2-autodiff-higher-order.cpp2" +#line 207 "pure2-autodiff-higher-order.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -464,37 +482,51 @@ return std::move(ret.value()); } return std::move(r.value()); } #line 68 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::prefix_add(cpp2::impl::in x, cpp2::impl::in y) -> prefix_add_ret{ + cpp2::impl::deferred_init r; +#line 69 "pure2-autodiff-higher-order.cpp2" + r.construct(+x + y); + return std::move(r.value()); } + +#line 72 "pure2-autodiff-higher-order.cpp2" + [[nodiscard]] auto ad_test::prefix_sub(cpp2::impl::in x, cpp2::impl::in y) -> prefix_sub_ret{ + cpp2::impl::deferred_init r; +#line 73 "pure2-autodiff-higher-order.cpp2" + r.construct(-x + y); + return std::move(r.value()); } + +#line 76 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 69 "pure2-autodiff-higher-order.cpp2" +#line 77 "pure2-autodiff-higher-order.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 72 "pure2-autodiff-higher-order.cpp2" +#line 80 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 73 "pure2-autodiff-higher-order.cpp2" +#line 81 "pure2-autodiff-higher-order.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 76 "pure2-autodiff-higher-order.cpp2" +#line 84 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 77 "pure2-autodiff-higher-order.cpp2" +#line 85 "pure2-autodiff-higher-order.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } -#line 80 "pure2-autodiff-higher-order.cpp2" +#line 88 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 81 "pure2-autodiff-higher-order.cpp2" +#line 89 "pure2-autodiff-higher-order.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 84 "pure2-autodiff-higher-order.cpp2" +#line 92 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 85 "pure2-autodiff-higher-order.cpp2" +#line 93 "pure2-autodiff-higher-order.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -502,10 +534,10 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 92 "pure2-autodiff-higher-order.cpp2" +#line 100 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 93 "pure2-autodiff-higher-order.cpp2" +#line 101 "pure2-autodiff-higher-order.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -514,24 +546,24 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 101 "pure2-autodiff-higher-order.cpp2" +#line 109 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 105 "pure2-autodiff-higher-order.cpp2" +#line 113 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 106 "pure2-autodiff-higher-order.cpp2" +#line 114 "pure2-autodiff-higher-order.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 111 "pure2-autodiff-higher-order.cpp2" +#line 119 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 112 "pure2-autodiff-higher-order.cpp2" +#line 120 "pure2-autodiff-higher-order.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -539,40 +571,40 @@ return std::move(ret.value()); } static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 119 "pure2-autodiff-higher-order.cpp2" +#line 127 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 120 "pure2-autodiff-higher-order.cpp2" +#line 128 "pure2-autodiff-higher-order.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 126 "pure2-autodiff-higher-order.cpp2" +#line 134 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 127 "pure2-autodiff-higher-order.cpp2" +#line 135 "pure2-autodiff-higher-order.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 133 "pure2-autodiff-higher-order.cpp2" +#line 141 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 134 "pure2-autodiff-higher-order.cpp2" +#line 142 "pure2-autodiff-higher-order.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 140 "pure2-autodiff-higher-order.cpp2" +#line 148 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 141 "pure2-autodiff-higher-order.cpp2" +#line 149 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -581,10 +613,10 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 149 "pure2-autodiff-higher-order.cpp2" +#line 157 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 150 "pure2-autodiff-higher-order.cpp2" +#line 158 "pure2-autodiff-higher-order.cpp2" int i {0}; r.construct(x); @@ -595,10 +627,10 @@ return std::move(ret.value()); } cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 160 "pure2-autodiff-higher-order.cpp2" +#line 168 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 161 "pure2-autodiff-higher-order.cpp2" +#line 169 "pure2-autodiff-higher-order.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -612,20 +644,20 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 174 "pure2-autodiff-higher-order.cpp2" +#line 182 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ cpp2::impl::deferred_init r; -#line 175 "pure2-autodiff-higher-order.cpp2" +#line 183 "pure2-autodiff-higher-order.cpp2" type_outer t {}; t.a = x; r.construct(cpp2::move(t).a + y); return std::move(r.value()); } -#line 181 "pure2-autodiff-higher-order.cpp2" +#line 189 "pure2-autodiff-higher-order.cpp2" [[nodiscard]] auto ad_test::type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret{ cpp2::impl::deferred_init r; -#line 182 "pure2-autodiff-higher-order.cpp2" +#line 190 "pure2-autodiff-higher-order.cpp2" type_outer t {}; t.a = x; @@ -736,6 +768,28 @@ cpp2::taylor temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto ad_test::prefix_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_add_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::taylor temp_1_d {+x_d}; + + double temp_1 {+x}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::prefix_sub_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_sub_d_ret{ + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::taylor temp_1_d {-x_d}; + + double temp_1 {-x}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret{ double ret {0.0}; cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; @@ -972,28 +1026,28 @@ type_outer_d t_d {}; return { std::move(r), std::move(r_d) }; } -#line 188 "pure2-autodiff-higher-order.cpp2" +#line 196 "pure2-autodiff-higher-order.cpp2" } -#line 190 "pure2-autodiff-higher-order.cpp2" +#line 198 "pure2-autodiff-higher-order.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + "):" << std::endl; std::cout << " r = " + cpp2::to_string(ret.r) + "" << std::endl; { auto i{1}; -#line 194 "pure2-autodiff-higher-order.cpp2" +#line 202 "pure2-autodiff-higher-order.cpp2" for( ; cpp2::impl::cmp_less_eq(i,ad_order); i += 1 ) { std::cout << " d" + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.r_d, i)) + "" << std::endl; } } -#line 197 "pure2-autodiff-higher-order.cpp2" +#line 205 "pure2-autodiff-higher-order.cpp2" } -#line 199 "pure2-autodiff-higher-order.cpp2" +#line 207 "pure2-autodiff-higher-order.cpp2" auto main() -> int{ -#line 202 "pure2-autodiff-higher-order.cpp2" +#line 210 "pure2-autodiff-higher-order.cpp2" double x {2.0}; ad_type x_d {1.0}; double y {3.0}; @@ -1011,6 +1065,8 @@ auto main() -> int{ write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("+x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_add_d(x, x_d, y, y_d)); + write_output("-x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_sub_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 1f583c777..90bf689bd 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -110,6 +110,24 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + prefix_add:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = +x + y; + return; + } + + prefix_sub:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = -x + y; + return; + } + func:( in x: double, in y: double, @@ -498,6 +516,40 @@ ad_test:/* @autodiff<"order=6"> @print */ type = return; } + prefix_add_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: cpp2::taylor = +x_d; + temp_1: double = +x; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } + + prefix_sub_d:( + in x: double, + in x_d: cpp2::taylor, + in y: double, + in y_d: cpp2::taylor, + ) -> ( + out r: double = 0.0, + out r_d: cpp2::taylor = 0.0, + ) = + { + temp_1_d: cpp2::taylor = -x_d; + temp_1: double = -x; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } + func_d:( in x: double, in x_d: cpp2::taylor, diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index e17b78012..a1f7ddf4b 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -18,7 +18,7 @@ class type_outer; #line 15 "pure2-autodiff.cpp2" class ad_test; -#line 185 "pure2-autodiff.cpp2" +#line 193 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -126,88 +126,98 @@ using add_mul_ret = double; #line 61 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; -using func_ret = double; +using prefix_add_ret = double; #line 65 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto prefix_add(cpp2::impl::in x, cpp2::impl::in y) -> prefix_add_ret; +using prefix_sub_ret = double; + + +#line 69 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto prefix_sub(cpp2::impl::in x, cpp2::impl::in y) -> prefix_sub_ret; +using func_ret = double; + + +#line 73 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 69 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 73 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using sin_call_ret = double; -#line 77 "pure2-autodiff.cpp2" +#line 85 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using if_branch_ret = double; -#line 81 "pure2-autodiff.cpp2" +#line 89 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret; using if_else_branch_ret = double; -#line 89 "pure2-autodiff.cpp2" +#line 97 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret; -#line 98 "pure2-autodiff.cpp2" +#line 106 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double; using intermediate_var_ret = double; -#line 102 "pure2-autodiff.cpp2" +#line 110 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret; using intermediate_passive_var_ret = double; -#line 108 "pure2-autodiff.cpp2" +#line 116 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret; using intermediate_untyped_ret = double; -#line 116 "pure2-autodiff.cpp2" +#line 124 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret; using intermediate_default_init_ret = double; -#line 123 "pure2-autodiff.cpp2" +#line 131 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret; using intermediate_no_init_ret = double; -#line 130 "pure2-autodiff.cpp2" +#line 138 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret; using while_loop_ret = double; -#line 137 "pure2-autodiff.cpp2" +#line 145 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret; using do_while_loop_ret = double; -#line 146 "pure2-autodiff.cpp2" +#line 154 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 157 "pure2-autodiff.cpp2" +#line 165 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; using type_outer_use_ret = double; -#line 171 "pure2-autodiff.cpp2" +#line 179 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; using type_outer_call_ret = double; -#line 178 "pure2-autodiff.cpp2" +#line 186 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret; struct add_1_d_ret { double r; double r_d; }; @@ -258,6 +268,14 @@ struct add_mul_d_ret { double r; double r_d; }; public: [[nodiscard]] static auto add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret; +struct prefix_add_d_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto prefix_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_add_d_ret; + +struct prefix_sub_d_ret { double r; double r_d; }; + +public: [[nodiscard]] static auto prefix_sub_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_sub_d_ret; + struct func_d_ret { double ret; double ret_d; }; public: [[nodiscard]] static auto func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret; @@ -331,14 +349,14 @@ public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cp public: auto operator=(ad_test const&) -> void = delete; -#line 184 "pure2-autodiff.cpp2" +#line 192 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 188 "pure2-autodiff.cpp2" +#line 196 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -358,12 +376,12 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 191 "pure2-autodiff.cpp2" +#line 199 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 197 "pure2-autodiff.cpp2" +#line 205 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -483,37 +501,51 @@ return std::move(ret.value()); } return std::move(r.value()); } #line 65 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::prefix_add(cpp2::impl::in x, cpp2::impl::in y) -> prefix_add_ret{ + cpp2::impl::deferred_init r; +#line 66 "pure2-autodiff.cpp2" + r.construct(+x + y); + return std::move(r.value()); } + +#line 69 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test::prefix_sub(cpp2::impl::in x, cpp2::impl::in y) -> prefix_sub_ret{ + cpp2::impl::deferred_init r; +#line 70 "pure2-autodiff.cpp2" + r.construct(-x + y); + return std::move(r.value()); } + +#line 73 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 66 "pure2-autodiff.cpp2" +#line 74 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 69 "pure2-autodiff.cpp2" +#line 77 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 70 "pure2-autodiff.cpp2" +#line 78 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 73 "pure2-autodiff.cpp2" +#line 81 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 74 "pure2-autodiff.cpp2" +#line 82 "pure2-autodiff.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } -#line 77 "pure2-autodiff.cpp2" +#line 85 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 78 "pure2-autodiff.cpp2" +#line 86 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 81 "pure2-autodiff.cpp2" +#line 89 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_branch_ret{ cpp2::impl::deferred_init r; -#line 82 "pure2-autodiff.cpp2" +#line 90 "pure2-autodiff.cpp2" r.construct(x); if (cpp2::impl::cmp_less(x,0.0)) { @@ -521,10 +553,10 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 89 "pure2-autodiff.cpp2" +#line 97 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::if_else_branch(cpp2::impl::in x, cpp2::impl::in y) -> if_else_branch_ret{ cpp2::impl::deferred_init r; -#line 90 "pure2-autodiff.cpp2" +#line 98 "pure2-autodiff.cpp2" if (cpp2::impl::cmp_less(x,0.0)) { r.construct(y); } @@ -533,24 +565,24 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 98 "pure2-autodiff.cpp2" +#line 106 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::direct_return(cpp2::impl::in x, cpp2::impl::in y) -> double{ return x + y; } -#line 102 "pure2-autodiff.cpp2" +#line 110 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_var_ret{ cpp2::impl::deferred_init r; -#line 103 "pure2-autodiff.cpp2" +#line 111 "pure2-autodiff.cpp2" double t {x + y}; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 108 "pure2-autodiff.cpp2" +#line 116 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; -#line 109 "pure2-autodiff.cpp2" +#line 117 "pure2-autodiff.cpp2" int i {}; // TODO: Handle as passive when type information on call side is available. r.construct(x + y); i = 2; @@ -558,40 +590,40 @@ return std::move(ret.value()); } static_cast(cpp2::move(i)); return std::move(r.value()); } -#line 116 "pure2-autodiff.cpp2" +#line 124 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_untyped(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_untyped_ret{ cpp2::impl::deferred_init r; -#line 117 "pure2-autodiff.cpp2" +#line 125 "pure2-autodiff.cpp2" auto t {0.0}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 123 "pure2-autodiff.cpp2" +#line 131 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_default_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_default_init_ret{ cpp2::impl::deferred_init r; -#line 124 "pure2-autodiff.cpp2" +#line 132 "pure2-autodiff.cpp2" double t {}; t = x + y; r.construct(cpp2::move(t)); return std::move(r.value()); } -#line 130 "pure2-autodiff.cpp2" +#line 138 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::intermediate_no_init(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_no_init_ret{ cpp2::impl::deferred_init r; -#line 131 "pure2-autodiff.cpp2" +#line 139 "pure2-autodiff.cpp2" cpp2::impl::deferred_init t; t.construct(x + y); r.construct(cpp2::move(t.value())); return std::move(r.value()); } -#line 137 "pure2-autodiff.cpp2" +#line 145 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; -#line 138 "pure2-autodiff.cpp2" +#line 146 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -600,10 +632,10 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 146 "pure2-autodiff.cpp2" +#line 154 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 147 "pure2-autodiff.cpp2" +#line 155 "pure2-autodiff.cpp2" int i {0}; r.construct(x); @@ -614,10 +646,10 @@ return std::move(ret.value()); } cpp2::impl::cmp_less(i,2));return std::move(r.value()); } -#line 157 "pure2-autodiff.cpp2" +#line 165 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 158 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -631,20 +663,20 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 171 "pure2-autodiff.cpp2" +#line 179 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ cpp2::impl::deferred_init r; -#line 172 "pure2-autodiff.cpp2" +#line 180 "pure2-autodiff.cpp2" type_outer t {}; t.a = x; r.construct(cpp2::move(t).a + y); return std::move(r.value()); } -#line 178 "pure2-autodiff.cpp2" +#line 186 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret{ cpp2::impl::deferred_init r; -#line 179 "pure2-autodiff.cpp2" +#line 187 "pure2-autodiff.cpp2" type_outer t {}; t.a = x; @@ -755,6 +787,28 @@ double temp_1_d {x * y_d + y * x_d}; return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto ad_test::prefix_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_add_d_ret{ + double r {0.0}; + double r_d {0.0}; +double temp_1_d {+x_d}; + + double temp_1 {+x}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + + [[nodiscard]] auto ad_test::prefix_sub_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_sub_d_ret{ + double r {0.0}; + double r_d {0.0}; +double temp_1_d {-x_d}; + + double temp_1 {-x}; + r_d = cpp2::move(temp_1_d) + y_d; + r = cpp2::move(temp_1) + y; + return { std::move(r), std::move(r_d) }; + } + [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret{ double ret {0.0}; double ret_d {0.0};ret_d = x_d + y_d; @@ -991,13 +1045,13 @@ type_outer_d t_d {}; return { std::move(r), std::move(r_d) }; } -#line 185 "pure2-autodiff.cpp2" +#line 193 "pure2-autodiff.cpp2" } -#line 188 "pure2-autodiff.cpp2" +#line 196 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 189 "pure2-autodiff.cpp2" +#line 197 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -1034,12 +1088,12 @@ double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 193 "pure2-autodiff.cpp2" +#line 201 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 197 "pure2-autodiff.cpp2" +#line 205 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -1059,6 +1113,8 @@ auto main() -> int{ write_output("x * y / x", x, x_d, y, y_d, ad_name::ad_test::mul_div_2_d(x, x_d, y, y_d)); write_output("x * (x + y)", x, x_d, y, y_d, ad_name::ad_test::mul_add_d(x, x_d, y, y_d)); write_output("x + x * y", x, x_d, y, y_d, ad_name::ad_test::add_mul_d(x, x_d, y, y_d)); + write_output("+x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_add_d(x, x_d, y, y_d)); + write_output("-x + y)", x, x_d, y, y_d, ad_name::ad_test::prefix_sub_d(x, x_d, y, y_d)); write_output("x * func(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_call_d(x, x_d, y, y_d)); write_output("x * func_outer(x, y)", x, x_d, y, y_d, ad_name::ad_test::func_outer_call_d(x, x_d, y, y_d)); write_output("sin(x - y)", x, x_d, y, y_d, ad_name::ad_test::sin_call_d(x, x_d, y, y_d)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 27e351b93..7b43c59f6 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -110,6 +110,24 @@ ad_test:/* @autodiff @print */ type = return; } + prefix_add:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = +x + y; + return; + } + + prefix_sub:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = -x + y; + return; + } + func:( in x: double, in y: double, @@ -498,6 +516,40 @@ ad_test:/* @autodiff @print */ type = return; } + prefix_add_d:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: double = +x_d; + temp_1: double = +x; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } + + prefix_sub_d:( + in x: double, + in x_d: double, + in y: double, + in y_d: double, + ) -> ( + out r: double = 0.0, + out r_d: double = 0.0, + ) = + { + temp_1_d: double = -x_d; + temp_1: double = -x; + r_d = temp_1_d + y_d; + r = temp_1 + y; + return; + } + func_d:( in x: double, in x_d: double, diff --git a/source/reflect.h b/source/reflect.h index faffa2f3e..60588cb3c 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -129,83 +129,83 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 4836 "reflect.h2" +#line 4847 "reflect.h2" class autodiff_stmt_handler; -#line 5097 "reflect.h2" +#line 5108 "reflect.h2" class autodiff_declaration_handler; -#line 5353 "reflect.h2" +#line 5364 "reflect.h2" class expression_flags; -#line 5369 "reflect.h2" +#line 5380 "reflect.h2" class regex_token; -#line 5396 "reflect.h2" +#line 5407 "reflect.h2" class regex_token_check; -#line 5417 "reflect.h2" +#line 5428 "reflect.h2" class regex_token_code; -#line 5438 "reflect.h2" +#line 5449 "reflect.h2" class regex_token_empty; -#line 5456 "reflect.h2" +#line 5467 "reflect.h2" class regex_token_list; -#line 5508 "reflect.h2" +#line 5519 "reflect.h2" class parse_context_group_state; -#line 5569 "reflect.h2" +#line 5580 "reflect.h2" class parse_context_branch_reset_state; -#line 5612 "reflect.h2" +#line 5623 "reflect.h2" class parse_context; -#line 6013 "reflect.h2" +#line 6024 "reflect.h2" class generation_function_context; -#line 6031 "reflect.h2" +#line 6042 "reflect.h2" class generation_context; -#line 6230 "reflect.h2" +#line 6241 "reflect.h2" class alternative_token; -#line 6245 "reflect.h2" +#line 6256 "reflect.h2" class alternative_token_gen; -#line 6310 "reflect.h2" +#line 6321 "reflect.h2" class any_token; -#line 6327 "reflect.h2" +#line 6338 "reflect.h2" class atomic_group_token; -#line 6357 "reflect.h2" +#line 6368 "reflect.h2" class char_token; -#line 6472 "reflect.h2" +#line 6483 "reflect.h2" class class_token; -#line 6696 "reflect.h2" +#line 6707 "reflect.h2" class group_ref_token; -#line 6833 "reflect.h2" +#line 6844 "reflect.h2" class group_token; -#line 7180 "reflect.h2" +#line 7191 "reflect.h2" class lookahead_lookbehind_token; -#line 7275 "reflect.h2" +#line 7286 "reflect.h2" class range_token; -#line 7432 "reflect.h2" +#line 7443 "reflect.h2" class special_range_token; -#line 7518 "reflect.h2" +#line 7529 "reflect.h2" template class regex_generator; -#line 7775 "reflect.h2" +#line 7786 "reflect.h2" } } @@ -1955,117 +1955,117 @@ public: primal_fwd_name(); #line 4758 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4763 "reflect.h2" +#line 4774 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4803 "reflect.h2" +#line 4814 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4834 "reflect.h2" +#line 4845 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4840 "reflect.h2" +#line 4851 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4849 "reflect.h2" +#line 4860 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4854 "reflect.h2" +#line 4865 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4859 "reflect.h2" +#line 4870 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4888 "reflect.h2" +#line 4899 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4893 "reflect.h2" +#line 4904 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4898 "reflect.h2" +#line 4909 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4903 "reflect.h2" +#line 4914 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4911 "reflect.h2" +#line 4922 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4928 "reflect.h2" +#line 4939 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4978 "reflect.h2" +#line 4989 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4989 "reflect.h2" +#line 5000 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4993 "reflect.h2" +#line 5004 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5006 "reflect.h2" +#line 5017 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5010 "reflect.h2" +#line 5021 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5014 "reflect.h2" +#line 5025 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5018 "reflect.h2" +#line 5029 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5022 "reflect.h2" +#line 5033 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5026 "reflect.h2" +#line 5037 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5030 "reflect.h2" +#line 5041 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5034 "reflect.h2" +#line 5045 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5038 "reflect.h2" +#line 5049 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5042 "reflect.h2" +#line 5053 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5046 "reflect.h2" +#line 5057 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5050 "reflect.h2" +#line 5061 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5054 "reflect.h2" +#line 5065 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5059 "reflect.h2" +#line 5070 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5091 "reflect.h2" +#line 5102 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5095 "reflect.h2" +#line 5106 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5101 "reflect.h2" +#line 5112 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2075,37 +2075,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 5113 "reflect.h2" +#line 5124 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5118 "reflect.h2" +#line 5129 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5198 "reflect.h2" +#line 5209 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5226 "reflect.h2" +#line 5237 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5250 "reflect.h2" +#line 5261 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5255 "reflect.h2" +#line 5266 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5258 "reflect.h2" +#line 5269 "reflect.h2" }; -#line 5261 "reflect.h2" +#line 5272 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5349 "reflect.h2" +#line 5360 "reflect.h2" using error_func = std::function x)>; -#line 5353 "reflect.h2" +#line 5364 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2140,20 +2140,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5361 "reflect.h2" +#line 5372 "reflect.h2" }; -#line 5369 "reflect.h2" +#line 5380 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5377 "reflect.h2" +#line 5388 "reflect.h2" public: explicit regex_token(); -#line 5382 "reflect.h2" +#line 5393 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2165,103 +2165,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5388 "reflect.h2" +#line 5399 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5394 "reflect.h2" +#line 5405 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5400 "reflect.h2" +#line 5411 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5407 "reflect.h2" +#line 5418 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5411 "reflect.h2" +#line 5422 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5412 "reflect.h2" +#line 5423 "reflect.h2" }; -#line 5415 "reflect.h2" +#line 5426 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5421 "reflect.h2" +#line 5432 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5428 "reflect.h2" +#line 5439 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5432 "reflect.h2" +#line 5443 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5433 "reflect.h2" +#line 5444 "reflect.h2" }; -#line 5436 "reflect.h2" +#line 5447 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5442 "reflect.h2" +#line 5453 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5446 "reflect.h2" +#line 5457 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5450 "reflect.h2" +#line 5461 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5451 "reflect.h2" +#line 5462 "reflect.h2" }; -#line 5454 "reflect.h2" +#line 5465 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5460 "reflect.h2" +#line 5471 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5467 "reflect.h2" +#line 5478 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5473 "reflect.h2" +#line 5484 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5479 "reflect.h2" +#line 5490 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5487 "reflect.h2" +#line 5498 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2269,10 +2269,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5499 "reflect.h2" +#line 5510 "reflect.h2" }; -#line 5502 "reflect.h2" +#line 5513 "reflect.h2" // // Parse and generation context. // @@ -2288,33 +2288,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5522 "reflect.h2" +#line 5533 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5529 "reflect.h2" +#line 5540 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5541 "reflect.h2" +#line 5552 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5546 "reflect.h2" +#line 5557 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5550 "reflect.h2" +#line 5561 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5564 "reflect.h2" +#line 5575 "reflect.h2" }; -#line 5567 "reflect.h2" +#line 5578 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2327,25 +2327,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5585 "reflect.h2" +#line 5596 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5591 "reflect.h2" +#line 5602 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5598 "reflect.h2" +#line 5609 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5605 "reflect.h2" +#line 5616 "reflect.h2" }; -#line 5608 "reflect.h2" +#line 5619 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2361,7 +2361,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5624 "reflect.h2" +#line 5635 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2369,64 +2369,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5635 "reflect.h2" +#line 5646 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5648 "reflect.h2" +#line 5659 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5656 "reflect.h2" +#line 5667 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5660 "reflect.h2" +#line 5671 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5664 "reflect.h2" +#line 5675 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5676 "reflect.h2" +#line 5687 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5683 "reflect.h2" +#line 5694 "reflect.h2" public: auto next_alternative() & -> void; -#line 5689 "reflect.h2" +#line 5700 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5695 "reflect.h2" +#line 5706 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5699 "reflect.h2" +#line 5710 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5710 "reflect.h2" +#line 5721 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5714 "reflect.h2" +#line 5725 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5720 "reflect.h2" +#line 5731 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5724 "reflect.h2" +#line 5735 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5731 "reflect.h2" +#line 5742 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5742 "reflect.h2" +#line 5753 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2434,51 +2434,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5786 "reflect.h2" +#line 5797 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5798 "reflect.h2" +#line 5809 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5811 "reflect.h2" +#line 5822 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5834 "reflect.h2" +#line 5845 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5851 "reflect.h2" +#line 5862 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5872 "reflect.h2" +#line 5883 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5882 "reflect.h2" +#line 5893 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5886 "reflect.h2" +#line 5897 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5942 "reflect.h2" +#line 5953 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5981 "reflect.h2" +#line 5992 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 5996 "reflect.h2" +#line 6007 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2490,10 +2490,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6007 "reflect.h2" +#line 6018 "reflect.h2" }; -#line 6010 "reflect.h2" +#line 6021 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2503,16 +2503,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6024 "reflect.h2" +#line 6035 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6027 "reflect.h2" +#line 6038 "reflect.h2" }; -#line 6030 "reflect.h2" +#line 6041 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2532,68 +2532,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6052 "reflect.h2" +#line 6063 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6058 "reflect.h2" +#line 6069 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6067 "reflect.h2" +#line 6078 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6078 "reflect.h2" +#line 6089 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6085 "reflect.h2" +#line 6096 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6105 "reflect.h2" +#line 6116 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6115 "reflect.h2" +#line 6126 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6138 "reflect.h2" +#line 6149 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6146 "reflect.h2" +#line 6157 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6150 "reflect.h2" +#line 6161 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6156 "reflect.h2" +#line 6167 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6162 "reflect.h2" +#line 6173 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6172 "reflect.h2" +#line 6183 "reflect.h2" public: auto finish_context() & -> void; -#line 6180 "reflect.h2" +#line 6191 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6186 "reflect.h2" +#line 6197 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6190 "reflect.h2" +#line 6201 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6194 "reflect.h2" +#line 6205 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6218 "reflect.h2" +#line 6229 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2601,7 +2601,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6224 "reflect.h2" +#line 6235 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2621,27 +2621,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6243 "reflect.h2" +#line 6254 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6249 "reflect.h2" +#line 6260 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6256 "reflect.h2" +#line 6267 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6273 "reflect.h2" +#line 6284 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6280 "reflect.h2" +#line 6291 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6293 "reflect.h2" +#line 6304 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2649,19 +2649,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6305 "reflect.h2" +#line 6316 "reflect.h2" }; -#line 6308 "reflect.h2" +#line 6319 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6314 "reflect.h2" +#line 6325 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6318 "reflect.h2" +#line 6329 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2669,7 +2669,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6323 "reflect.h2" +#line 6334 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2677,17 +2677,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6331 "reflect.h2" +#line 6342 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6342 "reflect.h2" +#line 6353 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6350 "reflect.h2" +#line 6361 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2695,7 +2695,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6353 "reflect.h2" +#line 6364 "reflect.h2" }; // Regex syntax: a @@ -2703,34 +2703,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6361 "reflect.h2" +#line 6372 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6370 "reflect.h2" +#line 6381 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6376 "reflect.h2" +#line 6387 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6380 "reflect.h2" +#line 6391 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6403 "reflect.h2" +#line 6414 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6424 "reflect.h2" +#line 6435 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6442 "reflect.h2" +#line 6453 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6457 "reflect.h2" +#line 6468 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6463 "reflect.h2" +#line 6474 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2738,33 +2738,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6467 "reflect.h2" +#line 6478 "reflect.h2" }; -#line 6470 "reflect.h2" +#line 6481 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6476 "reflect.h2" +#line 6487 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6488 "reflect.h2" +#line 6499 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6614 "reflect.h2" +#line 6625 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6623 "reflect.h2" +#line 6634 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6628 "reflect.h2" +#line 6639 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2772,20 +2772,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6635 "reflect.h2" +#line 6646 "reflect.h2" }; -#line 6638 "reflect.h2" +#line 6649 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6679 "reflect.h2" +#line 6690 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6690 "reflect.h2" +#line 6701 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2795,20 +2795,20 @@ class class_token class group_ref_token : public regex_token { -#line 6700 "reflect.h2" +#line 6711 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6712 "reflect.h2" +#line 6723 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6813 "reflect.h2" +#line 6824 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6817 "reflect.h2" +#line 6828 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2816,10 +2816,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6820 "reflect.h2" +#line 6831 "reflect.h2" }; -#line 6823 "reflect.h2" +#line 6834 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2833,29 +2833,29 @@ class group_ref_token class group_token : public regex_token { -#line 6837 "reflect.h2" +#line 6848 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6859 "reflect.h2" +#line 6870 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6873 "reflect.h2" +#line 6884 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7032 "reflect.h2" +#line 7043 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7040 "reflect.h2" +#line 7051 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7058 "reflect.h2" +#line 7069 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7089 "reflect.h2" +#line 7100 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2864,25 +2864,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7096 "reflect.h2" +#line 7107 "reflect.h2" }; -#line 7099 "reflect.h2" +#line 7110 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7140 "reflect.h2" +#line 7151 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7160 "reflect.h2" +#line 7171 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7176 "reflect.h2" +#line 7187 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2890,20 +2890,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7184 "reflect.h2" +#line 7195 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7193 "reflect.h2" +#line 7204 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7204 "reflect.h2" +#line 7215 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7211 "reflect.h2" +#line 7222 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2911,26 +2911,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7214 "reflect.h2" +#line 7225 "reflect.h2" }; -#line 7217 "reflect.h2" +#line 7228 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7245 "reflect.h2" +#line 7256 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7273 "reflect.h2" +#line 7284 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7279 "reflect.h2" +#line 7290 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2940,22 +2940,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7359 "reflect.h2" +#line 7370 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7371 "reflect.h2" +#line 7382 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7384 "reflect.h2" +#line 7395 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7403 "reflect.h2" +#line 7414 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7413 "reflect.h2" +#line 7424 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7424 "reflect.h2" +#line 7435 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2963,16 +2963,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7427 "reflect.h2" +#line 7438 "reflect.h2" }; -#line 7430 "reflect.h2" +#line 7441 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7436 "reflect.h2" +#line 7447 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2981,7 +2981,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7466 "reflect.h2" +#line 7477 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2990,14 +2990,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7488 "reflect.h2" +#line 7499 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7510 "reflect.h2" +#line 7521 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3018,24 +3018,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7533 "reflect.h2" +#line 7544 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7568 "reflect.h2" +#line 7579 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7582 "reflect.h2" +#line 7593 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7594 "reflect.h2" +#line 7605 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7649 "reflect.h2" +#line 7660 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3046,7 +3046,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7775 "reflect.h2" +#line 7786 "reflect.h2" } } @@ -8522,10 +8522,21 @@ auto i{1}; #line 4758 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { - CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled."); + auto ops {CPP2_UFCS(get_ops)(prefix)}; + + if (CPP2_UFCS(ssize)(ops) != 1) { + CPP2_UFCS(error)(prefix, "AD: Can only handle one prefix operation. Expression is: " + cpp2::to_string(CPP2_UFCS(to_string)(prefix)) + ""); + } + + autodiff_expression_handler ad {ctx}; + CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_postfix_expression)(prefix)); + append(ad); + + primal_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(ops, 0) + ad.primal_expr; + fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 4763 "reflect.h2" +#line 4774 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8534,7 +8545,7 @@ auto i{1}; { auto i{0}; -#line 4770 "reflect.h2" +#line 4781 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8549,7 +8560,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4783 "reflect.h2" +#line 4794 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8570,7 +8581,7 @@ auto i{0}; } } -#line 4803 "reflect.h2" +#line 4814 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8603,26 +8614,26 @@ auto i{0}; }}}} } -#line 4844 "reflect.h2" +#line 4855 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4847 "reflect.h2" +#line 4858 "reflect.h2" } -#line 4849 "reflect.h2" +#line 4860 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4854 "reflect.h2" +#line 4865 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4859 "reflect.h2" +#line 4870 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8651,22 +8662,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 4888 "reflect.h2" +#line 4899 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4893 "reflect.h2" +#line 4904 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4898 "reflect.h2" +#line 4909 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4903 "reflect.h2" +#line 4914 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8674,7 +8685,7 @@ auto i{0}; diff += "}\n"; } -#line 4911 "reflect.h2" +#line 4922 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8691,7 +8702,7 @@ auto i{0}; } } -#line 4928 "reflect.h2" +#line 4939 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8741,7 +8752,7 @@ auto i{0}; }} } -#line 4978 "reflect.h2" +#line 4989 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8753,12 +8764,12 @@ auto i{0}; } } -#line 4989 "reflect.h2" +#line 5000 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4993 "reflect.h2" +#line 5004 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8772,73 +8783,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 5006 "reflect.h2" +#line 5017 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5010 "reflect.h2" +#line 5021 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5014 "reflect.h2" +#line 5025 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5018 "reflect.h2" +#line 5029 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5022 "reflect.h2" +#line 5033 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5026 "reflect.h2" +#line 5037 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5030 "reflect.h2" +#line 5041 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5034 "reflect.h2" +#line 5045 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5038 "reflect.h2" +#line 5049 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5042 "reflect.h2" +#line 5053 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5046 "reflect.h2" +#line 5057 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5050 "reflect.h2" +#line 5061 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5054 "reflect.h2" +#line 5065 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5059 "reflect.h2" +#line 5070 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8847,7 +8858,7 @@ auto i{0}; { auto i{0}; -#line 5066 "reflect.h2" +#line 5077 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8862,7 +8873,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5079 "reflect.h2" +#line 5090 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8875,27 +8886,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5091 "reflect.h2" +#line 5102 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5108 "reflect.h2" +#line 5119 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5111 "reflect.h2" +#line 5122 "reflect.h2" } -#line 5113 "reflect.h2" +#line 5124 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5118 "reflect.h2" +#line 5129 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8955,10 +8966,10 @@ auto i{0}; return ; } -#line 5178 "reflect.h2" +#line 5189 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5181 "reflect.h2" +#line 5192 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8975,7 +8986,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5198 "reflect.h2" +#line 5209 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9003,7 +9014,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5226 "reflect.h2" +#line 5237 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9027,17 +9038,17 @@ auto i{0}; } } -#line 5250 "reflect.h2" +#line 5261 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5255 "reflect.h2" +#line 5266 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5261 "reflect.h2" +#line 5272 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9073,7 +9084,7 @@ auto autodiff(meta::type_declaration& t) -> void ad_ctx.suffix = cpp2::move(suffix); CPP2_UFCS(set_order)(ad_ctx, order); -#line 5297 "reflect.h2" +#line 5308 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -9202,7 +9213,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5335 "reflect.h2" +#line 5346 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9218,11 +9229,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5351 "reflect.h2" +#line 5362 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5355 "reflect.h2" +#line 5366 "reflect.h2" // mod: i // mod: m // mod: s @@ -9230,116 +9241,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5364 "reflect.h2" +#line 5375 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5373 "reflect.h2" +#line 5384 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5375 "reflect.h2" +#line 5386 "reflect.h2" } -#line 5377 "reflect.h2" +#line 5388 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5379 "reflect.h2" +#line 5390 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5385 "reflect.h2" +#line 5396 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5386 "reflect.h2" +#line 5397 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5387 "reflect.h2" +#line 5398 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5402 "reflect.h2" +#line 5413 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5405 "reflect.h2" +#line 5416 "reflect.h2" } -#line 5407 "reflect.h2" +#line 5418 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5411 "reflect.h2" +#line 5422 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5423 "reflect.h2" +#line 5434 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5426 "reflect.h2" +#line 5437 "reflect.h2" } -#line 5428 "reflect.h2" +#line 5439 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5432 "reflect.h2" +#line 5443 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5442 "reflect.h2" +#line 5453 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5444 "reflect.h2" +#line 5455 "reflect.h2" } -#line 5446 "reflect.h2" +#line 5457 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5450 "reflect.h2" +#line 5461 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5462 "reflect.h2" +#line 5473 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5465 "reflect.h2" +#line 5476 "reflect.h2" } -#line 5467 "reflect.h2" +#line 5478 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5473 "reflect.h2" +#line 5484 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5479 "reflect.h2" +#line 5490 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9348,7 +9359,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5487 "reflect.h2" +#line 5498 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9364,7 +9375,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5515 "reflect.h2" +#line 5526 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9372,14 +9383,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5523 "reflect.h2" +#line 5534 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5530 "reflect.h2" +#line 5541 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9391,15 +9402,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5542 "reflect.h2" +#line 5553 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5547 "reflect.h2" +#line 5558 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5551 "reflect.h2" +#line 5562 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9420,7 +9431,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5577 "reflect.h2" +#line 5588 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9429,20 +9440,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5586 "reflect.h2" +#line 5597 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5592 "reflect.h2" +#line 5603 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5599 "reflect.h2" +#line 5610 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9457,16 +9468,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5629 "reflect.h2" +#line 5640 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5633 "reflect.h2" +#line 5644 "reflect.h2" } -#line 5639 "reflect.h2" +#line 5650 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9476,7 +9487,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5649 "reflect.h2" +#line 5660 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9484,17 +9495,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5656 "reflect.h2" +#line 5667 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5660 "reflect.h2" +#line 5671 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5667 "reflect.h2" +#line 5678 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9504,7 +9515,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5676 "reflect.h2" +#line 5687 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9512,24 +9523,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5683 "reflect.h2" +#line 5694 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5691 "reflect.h2" +#line 5702 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5695 "reflect.h2" +#line 5706 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5699 "reflect.h2" +#line 5710 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9541,22 +9552,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5710 "reflect.h2" +#line 5721 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5716 "reflect.h2" +#line 5727 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5720 "reflect.h2" +#line 5731 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5724 "reflect.h2" +#line 5735 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9564,7 +9575,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5731 "reflect.h2" +#line 5742 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9576,10 +9587,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5744 "reflect.h2" +#line 5755 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5747 "reflect.h2" +#line 5758 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9619,7 +9630,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5787 "reflect.h2" +#line 5798 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9631,14 +9642,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5798 "reflect.h2" +#line 5809 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5799 "reflect.h2" +#line 5810 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5800 "reflect.h2" +#line 5811 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5802 "reflect.h2" +#line 5813 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9648,10 +9659,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5811 "reflect.h2" +#line 5822 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5813 "reflect.h2" +#line 5824 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9673,14 +9684,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5834 "reflect.h2" +#line 5845 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5835 "reflect.h2" +#line 5846 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5836 "reflect.h2" +#line 5847 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5838 "reflect.h2" +#line 5849 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9694,7 +9705,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5851 "reflect.h2" +#line 5862 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9716,7 +9727,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5872 "reflect.h2" +#line 5883 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9727,12 +9738,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5882 "reflect.h2" +#line 5893 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5883 "reflect.h2" +#line 5894 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5888 "reflect.h2" +#line 5899 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9787,7 +9798,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5942 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9827,7 +9838,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5981 "reflect.h2" +#line 5992 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9843,21 +9854,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5998 "reflect.h2" +#line 6009 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 5999 "reflect.h2" +#line 6010 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6000 "reflect.h2" +#line 6011 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6002 "reflect.h2" +#line 6013 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6017 "reflect.h2" +#line 6028 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9865,7 +9876,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6024 "reflect.h2" +#line 6035 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9875,22 +9886,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6042 "reflect.h2" +#line 6053 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6047 "reflect.h2" +#line 6058 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6053 "reflect.h2" +#line 6064 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6059 "reflect.h2" +#line 6070 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9899,7 +9910,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6067 "reflect.h2" +#line 6078 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9911,7 +9922,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6078 "reflect.h2" +#line 6089 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9919,7 +9930,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6085 "reflect.h2" +#line 6096 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9940,7 +9951,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6106 "reflect.h2" +#line 6117 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9950,7 +9961,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6116 "reflect.h2" +#line 6127 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9973,33 +9984,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6140 "reflect.h2" +#line 6151 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6146 "reflect.h2" +#line 6157 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6150 "reflect.h2" +#line 6161 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6156 "reflect.h2" +#line 6167 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6164 "reflect.h2" +#line 6175 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10008,7 +10019,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6172 "reflect.h2" +#line 6183 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10017,22 +10028,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6182 "reflect.h2" +#line 6193 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6186 "reflect.h2" +#line 6197 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6190 "reflect.h2" +#line 6201 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6194 "reflect.h2" +#line 6205 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10056,18 +10067,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6219 "reflect.h2" +#line 6230 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6234 "reflect.h2" +#line 6245 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6236 "reflect.h2" +#line 6247 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10078,15 +10089,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6251 "reflect.h2" +#line 6262 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6254 "reflect.h2" +#line 6265 "reflect.h2" } -#line 6256 "reflect.h2" +#line 6267 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10104,7 +10115,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6273 "reflect.h2" +#line 6284 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10112,7 +10123,7 @@ generation_function_context::generation_function_context(){} } } -#line 6280 "reflect.h2" +#line 6291 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10126,7 +10137,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6293 "reflect.h2" +#line 6304 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10142,14 +10153,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6314 "reflect.h2" +#line 6325 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6316 "reflect.h2" +#line 6327 "reflect.h2" } -#line 6318 "reflect.h2" +#line 6329 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10158,11 +10169,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6333 "reflect.h2" +#line 6344 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6335 "reflect.h2" +#line 6346 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10170,7 +10181,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6342 "reflect.h2" +#line 6353 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10179,37 +10190,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6350 "reflect.h2" +#line 6361 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6364 "reflect.h2" +#line 6375 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6368 "reflect.h2" +#line 6379 "reflect.h2" } -#line 6370 "reflect.h2" +#line 6381 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6374 "reflect.h2" +#line 6385 "reflect.h2" } -#line 6376 "reflect.h2" +#line 6387 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6380 "reflect.h2" +#line 6391 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10218,14 +10229,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6386 "reflect.h2" +#line 6397 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6391 "reflect.h2" +#line 6402 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10238,7 +10249,7 @@ size_t i{0}; } } -#line 6403 "reflect.h2" +#line 6414 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10260,7 +10271,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6424 "reflect.h2" +#line 6435 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10279,7 +10290,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6442 "reflect.h2" +#line 6453 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10295,14 +10306,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6457 "reflect.h2" +#line 6468 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6463 "reflect.h2" +#line 6474 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10310,19 +10321,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6480 "reflect.h2" +#line 6491 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6481 "reflect.h2" +#line 6492 "reflect.h2" { -#line 6486 "reflect.h2" +#line 6497 "reflect.h2" } -#line 6489 "reflect.h2" +#line 6500 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10448,7 +10459,7 @@ size_t i{0}; ); } -#line 6614 "reflect.h2" +#line 6625 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10458,13 +10469,13 @@ size_t i{0}; ); } -#line 6623 "reflect.h2" +#line 6634 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6628 "reflect.h2" +#line 6639 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10475,12 +10486,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6640 "reflect.h2" +#line 6651 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6645 "reflect.h2" +#line 6656 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10514,7 +10525,7 @@ size_t i{0}; } -#line 6681 "reflect.h2" +#line 6692 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10523,19 +10534,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6704 "reflect.h2" +#line 6715 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6705 "reflect.h2" +#line 6716 "reflect.h2" { -#line 6710 "reflect.h2" +#line 6721 "reflect.h2" } -#line 6712 "reflect.h2" +#line 6723 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10637,19 +10648,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6813 "reflect.h2" +#line 6824 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6817 "reflect.h2" +#line 6828 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6841 "reflect.h2" +#line 6852 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10668,7 +10679,7 @@ size_t i{0}; return r; } -#line 6859 "reflect.h2" +#line 6870 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10683,7 +10694,7 @@ size_t i{0}; return r; } -#line 6873 "reflect.h2" +#line 6884 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10843,7 +10854,7 @@ size_t i{0}; } } -#line 7032 "reflect.h2" +#line 7043 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10852,7 +10863,7 @@ size_t i{0}; return r; } -#line 7040 "reflect.h2" +#line 7051 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10871,7 +10882,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7058 "reflect.h2" +#line 7069 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10903,7 +10914,7 @@ size_t i{0}; } } -#line 7089 "reflect.h2" +#line 7100 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10914,7 +10925,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7101 "reflect.h2" +#line 7112 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10953,7 +10964,7 @@ size_t i{0}; return r; } -#line 7142 "reflect.h2" +#line 7153 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10971,7 +10982,7 @@ size_t i{0}; }} } -#line 7162 "reflect.h2" +#line 7173 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10985,16 +10996,16 @@ size_t i{0}; } } -#line 7188 "reflect.h2" +#line 7199 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7191 "reflect.h2" +#line 7202 "reflect.h2" } -#line 7193 "reflect.h2" +#line 7204 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11006,7 +11017,7 @@ size_t i{0}; } } -#line 7204 "reflect.h2" +#line 7215 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11014,14 +11025,14 @@ size_t i{0}; return r; } -#line 7211 "reflect.h2" +#line 7222 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7219 "reflect.h2" +#line 7230 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11047,7 +11058,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7247 "reflect.h2" +#line 7258 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11073,11 +11084,11 @@ size_t i{0}; return r; } -#line 7284 "reflect.h2" +#line 7295 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7286 "reflect.h2" +#line 7297 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11151,7 +11162,7 @@ size_t i{0}; return nullptr; } -#line 7359 "reflect.h2" +#line 7370 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11164,7 +11175,7 @@ size_t i{0}; }} } -#line 7371 "reflect.h2" +#line 7382 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11178,7 +11189,7 @@ size_t i{0}; }} } -#line 7384 "reflect.h2" +#line 7395 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11198,7 +11209,7 @@ size_t i{0}; return r; } -#line 7403 "reflect.h2" +#line 7414 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11209,7 +11220,7 @@ size_t i{0}; return r; } -#line 7413 "reflect.h2" +#line 7424 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11221,14 +11232,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7424 "reflect.h2" +#line 7435 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7436 "reflect.h2" +#line 7447 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11252,7 +11263,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7460 "reflect.h2" +#line 7471 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11262,7 +11273,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7472 "reflect.h2" +#line 7483 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11278,7 +11289,7 @@ size_t i{0}; } } -#line 7492 "reflect.h2" +#line 7503 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11296,15 +11307,15 @@ size_t i{0}; }} } -#line 7528 "reflect.h2" +#line 7539 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7531 "reflect.h2" +#line 7542 "reflect.h2" } -#line 7533 "reflect.h2" +#line 7544 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11340,7 +11351,7 @@ size_t i{0}; return source; } -#line 7568 "reflect.h2" +#line 7579 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11356,7 +11367,7 @@ size_t i{0}; } } -#line 7584 "reflect.h2" +#line 7595 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11365,7 +11376,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11420,7 +11431,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7653 "reflect.h2" +#line 7664 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11542,7 +11553,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7775 "reflect.h2" +#line 7786 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index b6ff60ab6..7a752349a 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4757,7 +4757,18 @@ autodiff_expression_handler: type = { traverse: (override inout this, prefix: meta::prefix_expression) = { - prefix.error( "AD: Prefix expressions are not yet handled." ); + ops := prefix.get_ops(); + + if ops.ssize() != 1 { + prefix.error( "AD: Can only handle one prefix operation. Expression is: (prefix.to_string())$" ); + } + + ad: autodiff_expression_handler = (ctx); + ad.pre_traverse(prefix.get_postfix_expression()); + append(ad); + + primal_expr = ops[0] + ad.primal_expr; + fwd_expr = ops[0] + ad.fwd_expr; } traverse: (override inout this, postfix: meta::postfix_expression) = From e1e391dd4aee5e917be312ee8e11341918a61e02 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 19 Aug 2025 12:27:50 +0200 Subject: [PATCH 38/54] Basic preperations for reverse mode AD. --- source/reflect.h | 1314 +++++++++++++++++++++++---------------------- source/reflect.h2 | 136 +++-- 2 files changed, 746 insertions(+), 704 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 60588cb3c..632a33668 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -121,91 +121,91 @@ class autodiff_declaration_stack_item; class autodiff_context; -#line 4326 "reflect.h2" +#line 4335 "reflect.h2" class autodiff_handler_base; -#line 4340 "reflect.h2" +#line 4349 "reflect.h2" class autodiff_expression_handler; -#line 4847 "reflect.h2" +#line 4856 "reflect.h2" class autodiff_stmt_handler; -#line 5108 "reflect.h2" +#line 5117 "reflect.h2" class autodiff_declaration_handler; -#line 5364 "reflect.h2" +#line 5384 "reflect.h2" class expression_flags; -#line 5380 "reflect.h2" +#line 5400 "reflect.h2" class regex_token; -#line 5407 "reflect.h2" +#line 5427 "reflect.h2" class regex_token_check; -#line 5428 "reflect.h2" +#line 5448 "reflect.h2" class regex_token_code; -#line 5449 "reflect.h2" +#line 5469 "reflect.h2" class regex_token_empty; -#line 5467 "reflect.h2" +#line 5487 "reflect.h2" class regex_token_list; -#line 5519 "reflect.h2" +#line 5539 "reflect.h2" class parse_context_group_state; -#line 5580 "reflect.h2" +#line 5600 "reflect.h2" class parse_context_branch_reset_state; -#line 5623 "reflect.h2" +#line 5643 "reflect.h2" class parse_context; -#line 6024 "reflect.h2" +#line 6044 "reflect.h2" class generation_function_context; -#line 6042 "reflect.h2" +#line 6062 "reflect.h2" class generation_context; -#line 6241 "reflect.h2" +#line 6261 "reflect.h2" class alternative_token; -#line 6256 "reflect.h2" +#line 6276 "reflect.h2" class alternative_token_gen; -#line 6321 "reflect.h2" +#line 6341 "reflect.h2" class any_token; -#line 6338 "reflect.h2" +#line 6358 "reflect.h2" class atomic_group_token; -#line 6368 "reflect.h2" +#line 6388 "reflect.h2" class char_token; -#line 6483 "reflect.h2" +#line 6503 "reflect.h2" class class_token; -#line 6707 "reflect.h2" +#line 6727 "reflect.h2" class group_ref_token; -#line 6844 "reflect.h2" +#line 6864 "reflect.h2" class group_token; -#line 7191 "reflect.h2" +#line 7211 "reflect.h2" class lookahead_lookbehind_token; -#line 7286 "reflect.h2" +#line 7306 "reflect.h2" class range_token; -#line 7443 "reflect.h2" +#line 7463 "reflect.h2" class special_range_token; -#line 7529 "reflect.h2" +#line 7549 "reflect.h2" template class regex_generator; -#line 7786 "reflect.h2" +#line 7806 "reflect.h2" } } @@ -1754,89 +1754,92 @@ class autodiff_context { "_od_.push_back(_ad1_);")}; #line 4086 "reflect.h2" - public: std::string suffix {"_d"}; + public: std::string fwd_suffix {"_d"}; + public: std::string rws_suffix {"_b"}; private: int order {1}; + public: bool reverse {false}; -#line 4090 "reflect.h2" - public: std::string ad_type {"double"}; +#line 4092 "reflect.h2" + public: std::string fwd_ad_type {"double"}; + public: std::string rws_ad_type {"double"}; public: std::map> declaration_map {}; public: std::vector declaration_stack {}; + public: explicit autodiff_context(); + public: autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_); + +#line 4115 "reflect.h2" public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member = false) & -> void; -#line 4099 "reflect.h2" +#line 4119 "reflect.h2" public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4116 "reflect.h2" - public: auto set_order(cpp2::impl::in new_order) & -> void; - -#line 4127 "reflect.h2" +#line 4136 "reflect.h2" public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4134 "reflect.h2" - public: [[nodiscard]] auto get_ad_type(cpp2::impl::in type) & -> std::string; +#line 4143 "reflect.h2" + public: [[nodiscard]] auto get_fwd_ad_type(cpp2::impl::in type) & -> std::string; using lookup_declaration_ret = std::vector; -#line 4152 "reflect.h2" +#line 4161 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; -#line 4175 "reflect.h2" +#line 4184 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4192 "reflect.h2" +#line 4201 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; using lookup_member_function_declaration_ret = std::vector; -#line 4202 "reflect.h2" +#line 4211 "reflect.h2" public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4212 "reflect.h2" +#line 4221 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4222 "reflect.h2" +#line 4231 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4244 "reflect.h2" +#line 4253 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4252 "reflect.h2" +#line 4261 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4272 "reflect.h2" +#line 4281 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4282 "reflect.h2" +#line 4291 "reflect.h2" public: auto enter_function() & -> void; -#line 4287 "reflect.h2" +#line 4296 "reflect.h2" public: auto leave_function() & -> void; -#line 4291 "reflect.h2" +#line 4300 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4304 "reflect.h2" +#line 4313 "reflect.h2" public: auto pop_stack() & -> void; -#line 4319 "reflect.h2" +#line 4328 "reflect.h2" public: auto finish() & -> void; - public: autodiff_context() = default; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4324 "reflect.h2" +#line 4333 "reflect.h2" }; class autodiff_handler_base { @@ -1845,21 +1848,21 @@ class autodiff_handler_base { public: std::string diff {""}; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4331 "reflect.h2" +#line 4340 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4335 "reflect.h2" +#line 4344 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4338 "reflect.h2" +#line 4347 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4344 "reflect.h2" +#line 4353 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1867,28 +1870,28 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4353 "reflect.h2" +#line 4362 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; -#line 4362 "reflect.h2" +#line 4371 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; -#line 4366 "reflect.h2" +#line 4375 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4372 "reflect.h2" +#line 4381 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; -#line 4376 "reflect.h2" +#line 4385 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4385 "reflect.h2" +#line 4394 "reflect.h2" public: class primal_fwd_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -1896,176 +1899,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_name(); -#line 4388 "reflect.h2" +#line 4397 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4399 "reflect.h2" +#line 4408 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_name; -#line 4450 "reflect.h2" +#line 4459 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4594 "reflect.h2" +#line 4603 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4629 "reflect.h2" +#line 4638 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4633 "reflect.h2" +#line 4642 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4637 "reflect.h2" +#line 4646 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4641 "reflect.h2" +#line 4650 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4645 "reflect.h2" +#line 4654 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4649 "reflect.h2" +#line 4658 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4653 "reflect.h2" +#line 4662 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4657 "reflect.h2" +#line 4666 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4661 "reflect.h2" +#line 4670 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4665 "reflect.h2" +#line 4674 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4669 "reflect.h2" +#line 4678 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4673 "reflect.h2" +#line 4682 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4697 "reflect.h2" +#line 4706 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4754 "reflect.h2" +#line 4763 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4758 "reflect.h2" +#line 4767 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4774 "reflect.h2" +#line 4783 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4814 "reflect.h2" +#line 4823 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4845 "reflect.h2" +#line 4854 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4851 "reflect.h2" +#line 4860 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4860 "reflect.h2" +#line 4869 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4865 "reflect.h2" +#line 4874 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4870 "reflect.h2" +#line 4879 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4899 "reflect.h2" +#line 4908 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4904 "reflect.h2" +#line 4913 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4909 "reflect.h2" +#line 4918 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4914 "reflect.h2" +#line 4923 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4922 "reflect.h2" +#line 4931 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4939 "reflect.h2" +#line 4948 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4989 "reflect.h2" +#line 4998 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5000 "reflect.h2" +#line 5009 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5004 "reflect.h2" +#line 5013 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5017 "reflect.h2" +#line 5026 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5021 "reflect.h2" +#line 5030 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5025 "reflect.h2" +#line 5034 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5029 "reflect.h2" +#line 5038 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5033 "reflect.h2" +#line 5042 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5037 "reflect.h2" +#line 5046 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5041 "reflect.h2" +#line 5050 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5045 "reflect.h2" +#line 5054 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5049 "reflect.h2" +#line 5058 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5053 "reflect.h2" +#line 5062 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5057 "reflect.h2" +#line 5066 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5061 "reflect.h2" +#line 5070 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5065 "reflect.h2" +#line 5074 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5070 "reflect.h2" +#line 5079 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5102 "reflect.h2" +#line 5111 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5106 "reflect.h2" +#line 5115 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5112 "reflect.h2" +#line 5121 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2075,37 +2078,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 5124 "reflect.h2" +#line 5133 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5129 "reflect.h2" +#line 5138 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5209 "reflect.h2" +#line 5218 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5237 "reflect.h2" +#line 5246 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5261 "reflect.h2" +#line 5270 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5266 "reflect.h2" +#line 5275 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5269 "reflect.h2" +#line 5278 "reflect.h2" }; -#line 5272 "reflect.h2" +#line 5281 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5360 "reflect.h2" +#line 5380 "reflect.h2" using error_func = std::function x)>; -#line 5364 "reflect.h2" +#line 5384 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2140,20 +2143,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5372 "reflect.h2" +#line 5392 "reflect.h2" }; -#line 5380 "reflect.h2" +#line 5400 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5388 "reflect.h2" +#line 5408 "reflect.h2" public: explicit regex_token(); -#line 5393 "reflect.h2" +#line 5413 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2165,103 +2168,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5399 "reflect.h2" +#line 5419 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5405 "reflect.h2" +#line 5425 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5411 "reflect.h2" +#line 5431 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5418 "reflect.h2" +#line 5438 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5422 "reflect.h2" +#line 5442 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5423 "reflect.h2" +#line 5443 "reflect.h2" }; -#line 5426 "reflect.h2" +#line 5446 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5432 "reflect.h2" +#line 5452 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5439 "reflect.h2" +#line 5459 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5443 "reflect.h2" +#line 5463 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5444 "reflect.h2" +#line 5464 "reflect.h2" }; -#line 5447 "reflect.h2" +#line 5467 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5453 "reflect.h2" +#line 5473 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5457 "reflect.h2" +#line 5477 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5461 "reflect.h2" +#line 5481 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5462 "reflect.h2" +#line 5482 "reflect.h2" }; -#line 5465 "reflect.h2" +#line 5485 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5471 "reflect.h2" +#line 5491 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5478 "reflect.h2" +#line 5498 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5484 "reflect.h2" +#line 5504 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5490 "reflect.h2" +#line 5510 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5498 "reflect.h2" +#line 5518 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2269,10 +2272,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5510 "reflect.h2" +#line 5530 "reflect.h2" }; -#line 5513 "reflect.h2" +#line 5533 "reflect.h2" // // Parse and generation context. // @@ -2288,33 +2291,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5533 "reflect.h2" +#line 5553 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5540 "reflect.h2" +#line 5560 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5552 "reflect.h2" +#line 5572 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5557 "reflect.h2" +#line 5577 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5561 "reflect.h2" +#line 5581 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5575 "reflect.h2" +#line 5595 "reflect.h2" }; -#line 5578 "reflect.h2" +#line 5598 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2327,25 +2330,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5596 "reflect.h2" +#line 5616 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5602 "reflect.h2" +#line 5622 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5609 "reflect.h2" +#line 5629 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5616 "reflect.h2" +#line 5636 "reflect.h2" }; -#line 5619 "reflect.h2" +#line 5639 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2361,7 +2364,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5635 "reflect.h2" +#line 5655 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2369,64 +2372,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5646 "reflect.h2" +#line 5666 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5659 "reflect.h2" +#line 5679 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5667 "reflect.h2" +#line 5687 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5671 "reflect.h2" +#line 5691 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5675 "reflect.h2" +#line 5695 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5687 "reflect.h2" +#line 5707 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5694 "reflect.h2" +#line 5714 "reflect.h2" public: auto next_alternative() & -> void; -#line 5700 "reflect.h2" +#line 5720 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5706 "reflect.h2" +#line 5726 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5710 "reflect.h2" +#line 5730 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5721 "reflect.h2" +#line 5741 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5725 "reflect.h2" +#line 5745 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5731 "reflect.h2" +#line 5751 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5735 "reflect.h2" +#line 5755 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5742 "reflect.h2" +#line 5762 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5753 "reflect.h2" +#line 5773 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2434,51 +2437,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5797 "reflect.h2" +#line 5817 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5809 "reflect.h2" +#line 5829 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5822 "reflect.h2" +#line 5842 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5845 "reflect.h2" +#line 5865 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5862 "reflect.h2" +#line 5882 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5883 "reflect.h2" +#line 5903 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5893 "reflect.h2" +#line 5913 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5897 "reflect.h2" +#line 5917 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5953 "reflect.h2" +#line 5973 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 5992 "reflect.h2" +#line 6012 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6007 "reflect.h2" +#line 6027 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2490,10 +2493,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6018 "reflect.h2" +#line 6038 "reflect.h2" }; -#line 6021 "reflect.h2" +#line 6041 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2503,16 +2506,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6035 "reflect.h2" +#line 6055 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6038 "reflect.h2" +#line 6058 "reflect.h2" }; -#line 6041 "reflect.h2" +#line 6061 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2532,68 +2535,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6063 "reflect.h2" +#line 6083 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6069 "reflect.h2" +#line 6089 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6078 "reflect.h2" +#line 6098 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6089 "reflect.h2" +#line 6109 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6096 "reflect.h2" +#line 6116 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6116 "reflect.h2" +#line 6136 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6126 "reflect.h2" +#line 6146 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6149 "reflect.h2" +#line 6169 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6157 "reflect.h2" +#line 6177 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6161 "reflect.h2" +#line 6181 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6167 "reflect.h2" +#line 6187 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6173 "reflect.h2" +#line 6193 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6183 "reflect.h2" +#line 6203 "reflect.h2" public: auto finish_context() & -> void; -#line 6191 "reflect.h2" +#line 6211 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6197 "reflect.h2" +#line 6217 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6201 "reflect.h2" +#line 6221 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6205 "reflect.h2" +#line 6225 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6229 "reflect.h2" +#line 6249 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2601,7 +2604,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6235 "reflect.h2" +#line 6255 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2621,27 +2624,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6254 "reflect.h2" +#line 6274 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6260 "reflect.h2" +#line 6280 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6267 "reflect.h2" +#line 6287 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6284 "reflect.h2" +#line 6304 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6291 "reflect.h2" +#line 6311 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6304 "reflect.h2" +#line 6324 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2649,19 +2652,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6316 "reflect.h2" +#line 6336 "reflect.h2" }; -#line 6319 "reflect.h2" +#line 6339 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6325 "reflect.h2" +#line 6345 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6329 "reflect.h2" +#line 6349 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2669,7 +2672,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6334 "reflect.h2" +#line 6354 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2677,17 +2680,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6342 "reflect.h2" +#line 6362 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6353 "reflect.h2" +#line 6373 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6361 "reflect.h2" +#line 6381 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2695,7 +2698,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6364 "reflect.h2" +#line 6384 "reflect.h2" }; // Regex syntax: a @@ -2703,34 +2706,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6372 "reflect.h2" +#line 6392 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6381 "reflect.h2" +#line 6401 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6387 "reflect.h2" +#line 6407 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6391 "reflect.h2" +#line 6411 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6414 "reflect.h2" +#line 6434 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6435 "reflect.h2" +#line 6455 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6453 "reflect.h2" +#line 6473 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6468 "reflect.h2" +#line 6488 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6474 "reflect.h2" +#line 6494 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2738,33 +2741,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6478 "reflect.h2" +#line 6498 "reflect.h2" }; -#line 6481 "reflect.h2" +#line 6501 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6487 "reflect.h2" +#line 6507 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6499 "reflect.h2" +#line 6519 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6625 "reflect.h2" +#line 6645 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6634 "reflect.h2" +#line 6654 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6639 "reflect.h2" +#line 6659 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2772,20 +2775,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6646 "reflect.h2" +#line 6666 "reflect.h2" }; -#line 6649 "reflect.h2" +#line 6669 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6690 "reflect.h2" +#line 6710 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6701 "reflect.h2" +#line 6721 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2795,20 +2798,20 @@ class class_token class group_ref_token : public regex_token { -#line 6711 "reflect.h2" +#line 6731 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6723 "reflect.h2" +#line 6743 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6824 "reflect.h2" +#line 6844 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6828 "reflect.h2" +#line 6848 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2816,10 +2819,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6831 "reflect.h2" +#line 6851 "reflect.h2" }; -#line 6834 "reflect.h2" +#line 6854 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2833,29 +2836,29 @@ class group_ref_token class group_token : public regex_token { -#line 6848 "reflect.h2" +#line 6868 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6870 "reflect.h2" +#line 6890 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6884 "reflect.h2" +#line 6904 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7043 "reflect.h2" +#line 7063 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7051 "reflect.h2" +#line 7071 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7069 "reflect.h2" +#line 7089 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7100 "reflect.h2" +#line 7120 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2864,25 +2867,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7107 "reflect.h2" +#line 7127 "reflect.h2" }; -#line 7110 "reflect.h2" +#line 7130 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7151 "reflect.h2" +#line 7171 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7171 "reflect.h2" +#line 7191 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7187 "reflect.h2" +#line 7207 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2890,20 +2893,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7195 "reflect.h2" +#line 7215 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7204 "reflect.h2" +#line 7224 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7215 "reflect.h2" +#line 7235 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7222 "reflect.h2" +#line 7242 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2911,26 +2914,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7225 "reflect.h2" +#line 7245 "reflect.h2" }; -#line 7228 "reflect.h2" +#line 7248 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7256 "reflect.h2" +#line 7276 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7284 "reflect.h2" +#line 7304 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7290 "reflect.h2" +#line 7310 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2940,22 +2943,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7370 "reflect.h2" +#line 7390 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7382 "reflect.h2" +#line 7402 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7395 "reflect.h2" +#line 7415 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7414 "reflect.h2" +#line 7434 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7424 "reflect.h2" +#line 7444 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7435 "reflect.h2" +#line 7455 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2963,16 +2966,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7438 "reflect.h2" +#line 7458 "reflect.h2" }; -#line 7441 "reflect.h2" +#line 7461 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7447 "reflect.h2" +#line 7467 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2981,7 +2984,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7477 "reflect.h2" +#line 7497 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2990,14 +2993,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7499 "reflect.h2" +#line 7519 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7521 "reflect.h2" +#line 7541 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3018,24 +3021,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7544 "reflect.h2" +#line 7564 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7579 "reflect.h2" +#line 7599 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7593 "reflect.h2" +#line 7613 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7605 "reflect.h2" +#line 7625 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7660 "reflect.h2" +#line 7680 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3046,7 +3049,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7786 "reflect.h2" +#line 7806 "reflect.h2" } } @@ -7785,15 +7788,35 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar #line 4081 "reflect.h2" /* is_member = */ -#line 4089 "reflect.h2" +#line 4091 "reflect.h2" // Members depending on order -#line 4095 "reflect.h2" +#line 4098 "reflect.h2" + autodiff_context::autodiff_context(){} +#line 4099 "reflect.h2" + autodiff_context::autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_) + : order{ order_ } + , reverse{ reverse_ }{ + +#line 4103 "reflect.h2" + if (1 != order) { + if (reverse) { + fwd_ad_type = "cpp2::taylor"; + rws_ad_type = "cpp2::taylor"; + } + else { + fwd_ad_type = "cpp2::taylor"; + } + } + + } + +#line 4115 "reflect.h2" auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member) & -> void{ CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_member)); } -#line 4099 "reflect.h2" +#line 4119 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -7811,29 +7834,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4116 "reflect.h2" - auto autodiff_context::set_order(cpp2::impl::in new_order) & -> void{ - order = new_order; - - if (1 == order) { - ad_type = "double"; - } - else { - ad_type = "cpp2::taylor"; - } - } - -#line 4127 "reflect.h2" +#line 4136 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4129 "reflect.h2" +#line 4138 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4134 "reflect.h2" - [[nodiscard]] auto autodiff_context::get_ad_type(cpp2::impl::in type) & -> std::string{ +#line 4143 "reflect.h2" + [[nodiscard]] auto autodiff_context::get_fwd_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; if ("double" != type) { @@ -7843,18 +7854,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar add_for_differentiation(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(type_decls), 0)); // Add the AD suffix to the type - type_d += suffix; + type_d += fwd_suffix; } } // Replace with AD type for the AD order. - return string_util::replace_all(cpp2::move(type_d), "double", ad_type); + return string_util::replace_all(cpp2::move(type_d), "double", fwd_ad_type); } -#line 4152 "reflect.h2" +#line 4161 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4153 "reflect.h2" +#line 4162 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7877,7 +7888,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4175 "reflect.h2" +#line 4184 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ if (name == "_") { return autodiff_declared_variable(name, "_", false); @@ -7895,10 +7906,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return autodiff_declared_variable(); } -#line 4192 "reflect.h2" +#line 4201 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4193 "reflect.h2" +#line 4202 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7908,10 +7919,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4202 "reflect.h2" +#line 4211 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ std::vector r {}; -#line 4203 "reflect.h2" +#line 4212 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); @@ -7921,10 +7932,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4212 "reflect.h2" +#line 4221 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4213 "reflect.h2" +#line 4222 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7934,12 +7945,12 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4222 "reflect.h2" +#line 4231 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4223 "reflect.h2" +#line 4232 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -7961,7 +7972,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4244 "reflect.h2" +#line 4253 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -7970,7 +7981,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4252 "reflect.h2" +#line 4261 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -7991,7 +8002,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4272 "reflect.h2" +#line 4281 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -8002,18 +8013,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4282 "reflect.h2" +#line 4291 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4287 "reflect.h2" +#line 4296 "reflect.h2" auto autodiff_context::leave_function() & -> void{ CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4291 "reflect.h2" +#line 4300 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -8027,7 +8038,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4304 "reflect.h2" +#line 4313 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -8043,77 +8054,77 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4319 "reflect.h2" +#line 4328 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4331 "reflect.h2" +#line 4340 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4333 "reflect.h2" +#line 4342 "reflect.h2" } -#line 4331 "reflect.h2" +#line 4340 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ""; return *this; -#line 4333 "reflect.h2" +#line 4342 "reflect.h2" } -#line 4335 "reflect.h2" +#line 4344 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff; } -#line 4349 "reflect.h2" +#line 4358 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4351 "reflect.h2" +#line 4360 "reflect.h2" } -#line 4353 "reflect.h2" +#line 4362 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ if ("_" == lhs) { return lhs; } else { - return lhs + (*cpp2::impl::assert_not_null(ctx)).suffix; + return lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; } } -#line 4362 "reflect.h2" +#line 4371 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4366 "reflect.h2" +#line 4375 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } -#line 4368 "reflect.h2" +#line 4377 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } -#line 4372 "reflect.h2" +#line 4381 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4376 "reflect.h2" +#line 4385 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4378 "reflect.h2" + return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } +#line 4387 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4380 "reflect.h2" + return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } +#line 4389 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } + return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } autodiff_expression_handler::primal_fwd_name::primal_fwd_name(auto&& primal_, auto&& fwd_) requires (std::is_convertible_v&> && std::is_convertible_v&>) @@ -8121,7 +8132,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8131,15 +8142,15 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} return args; } -#line 4399 "reflect.h2" +#line 4408 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; - auto fwd {primal + (*cpp2::impl::assert_not_null(ctx)).suffix}; + auto fwd {primal + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal)}; if (cpp2::move(decl).is_member) { - fwd = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "." + fwd; + fwd = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "." + fwd; } return { cpp2::move(primal), cpp2::move(fwd) }; } @@ -8163,7 +8174,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).suffix}; // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) static_cast(cpp2::move(t)); return r; } @@ -8177,13 +8188,13 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).suffix}; // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) static_cast(cpp2::move(t)); return r; }} } -#line 4450 "reflect.h2" +#line 4459 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8191,7 +8202,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} { auto i{0}; -#line 4456 "reflect.h2" +#line 4465 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8205,7 +8216,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4468 "reflect.h2" +#line 4477 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8220,7 +8231,7 @@ auto i{0}; if (1 != CPP2_UFCS(ssize)(terms)) { object = CPP2_UFCS(to_string)(primary); - object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + (*cpp2::impl::assert_not_null(ctx)).suffix; + object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; } else { function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); @@ -8228,7 +8239,7 @@ auto i{0}; { auto i{0}; -#line 4489 "reflect.h2" +#line 4498 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8239,7 +8250,7 @@ auto i{0}; } else { object += "." + name; - object_d += "." + cpp2::move(name) + (*cpp2::impl::assert_not_null(ctx)).suffix; + object_d += "." + cpp2::move(name) + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; } } else {if (CPP2_UFCS(get_op)(term) == "(") { @@ -8253,7 +8264,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4512 "reflect.h2" +#line 4521 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8274,7 +8285,7 @@ auto i{0}; if (!(CPP2_UFCS(empty)(object))) {// Prepend object call diff += "" + cpp2::to_string(object) + "."; } - diff += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "("; + diff += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "("; if (!(CPP2_UFCS(empty)(object))) {// Add this_d argument. diff += "" + cpp2::to_string(cpp2::move(object_d)) + ", "; } @@ -8327,7 +8338,7 @@ auto i{0}; } } - std::string ret_name_d {ret_name + (*cpp2::impl::assert_not_null(ctx)).suffix}; + std::string ret_name_d {ret_name + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; primal_expr = "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + ""; fwd_expr = "" + cpp2::to_string(cpp2::move(ret_temp)) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + ""; @@ -8336,7 +8347,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4594 "reflect.h2" +#line 4603 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8359,7 +8370,7 @@ auto i{0}; { auto i{1}; -#line 4615 "reflect.h2" +#line 4624 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8369,69 +8380,69 @@ auto i{1}; } } -#line 4623 "reflect.h2" +#line 4632 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4629 "reflect.h2" +#line 4638 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4633 "reflect.h2" +#line 4642 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4637 "reflect.h2" +#line 4646 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4641 "reflect.h2" +#line 4650 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4645 "reflect.h2" +#line 4654 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4649 "reflect.h2" +#line 4658 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4653 "reflect.h2" +#line 4662 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4657 "reflect.h2" +#line 4666 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4661 "reflect.h2" +#line 4670 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4665 "reflect.h2" +#line 4674 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4669 "reflect.h2" +#line 4678 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4673 "reflect.h2" +#line 4682 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8456,7 +8467,7 @@ auto i{1}; fwd_expr = cpp2::move(fwd); } -#line 4697 "reflect.h2" +#line 4706 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8497,7 +8508,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4738 "reflect.h2" +#line 4747 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8505,7 +8516,7 @@ auto i{1}; else { // Temporary auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).suffix}; + auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; gen_declaration(t, t_d, cpp2::move(primal), cpp2::move(fwd), "", ""); arg_a = cpp2::move(t); @@ -8514,12 +8525,12 @@ auto i{1}; } } -#line 4754 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4758 "reflect.h2" +#line 4767 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -8536,7 +8547,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 4774 "reflect.h2" +#line 4783 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8545,7 +8556,7 @@ auto i{1}; { auto i{0}; -#line 4781 "reflect.h2" +#line 4790 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8560,7 +8571,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4794 "reflect.h2" +#line 4803 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8569,11 +8580,11 @@ auto i{0}; auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; std::string obj_access {CPP2_UFCS(to_string)(cpp2::move(primary))}; - std::string obj_access_d {obj_access + (*cpp2::impl::assert_not_null(ctx)).suffix}; + std::string obj_access_d {obj_access + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; for ( auto const& term : cpp2::move(terms) ) { obj_access += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)); - obj_access_d += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)) + (*cpp2::impl::assert_not_null(ctx)).suffix; + obj_access_d += CPP2_UFCS(get_op)(term) + CPP2_UFCS(to_string)(CPP2_UFCS(get_id_expression)(term)) + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; } primal_expr = cpp2::move(obj_access); @@ -8581,7 +8592,7 @@ auto i{0}; } } -#line 4814 "reflect.h2" +#line 4823 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8590,7 +8601,7 @@ auto i{0}; auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal_expr)}; if (cpp2::move(decl).is_member) { - fwd_expr = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + "." + fwd_expr; + fwd_expr = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "." + fwd_expr; } } else {if (CPP2_UFCS(is_expression_list)(primary)) { @@ -8614,31 +8625,31 @@ auto i{0}; }}}} } -#line 4855 "reflect.h2" +#line 4864 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4858 "reflect.h2" +#line 4867 "reflect.h2" } -#line 4860 "reflect.h2" +#line 4869 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4865 "reflect.h2" +#line 4874 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4870 "reflect.h2" +#line 4879 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; - auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; std::string prim_init {""}; std::string fwd_init {""}; @@ -8653,31 +8664,31 @@ auto i{0}; if (type == "_" && cpp2::move(ad).fwd_expr == "()") { // Special handling for auto initialization from a literal. - fwd_init = " = " + CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; + fwd_init = " = " + CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; } } - diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(cpp2::move(ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; + diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 4899 "reflect.h2" +#line 4908 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4904 "reflect.h2" +#line 4913 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4909 "reflect.h2" +#line 4918 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4914 "reflect.h2" +#line 4923 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8685,7 +8696,7 @@ auto i{0}; diff += "}\n"; } -#line 4922 "reflect.h2" +#line 4931 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8702,7 +8713,7 @@ auto i{0}; } } -#line 4939 "reflect.h2" +#line 4948 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8735,7 +8746,7 @@ auto i{0}; auto param {CPP2_UFCS(get_for_parameter)(stmt)}; auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; - diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ".begin())\n"; + diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"; diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; if (CPP2_UFCS(has_next)(stmt)) { // TODO: Assumption is here that nothing is in the next expression @@ -8743,7 +8754,7 @@ auto i{0}; } diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; - diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "");// TODO: Handle loop/compound context variable declarations. @@ -8752,7 +8763,7 @@ auto i{0}; }} } -#line 4989 "reflect.h2" +#line 4998 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8764,12 +8775,12 @@ auto i{0}; } } -#line 5000 "reflect.h2" +#line 5009 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5004 "reflect.h2" +#line 5013 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8783,73 +8794,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 5017 "reflect.h2" +#line 5026 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5021 "reflect.h2" +#line 5030 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5025 "reflect.h2" +#line 5034 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5029 "reflect.h2" +#line 5038 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5033 "reflect.h2" +#line 5042 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5037 "reflect.h2" +#line 5046 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5041 "reflect.h2" +#line 5050 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5045 "reflect.h2" +#line 5054 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5049 "reflect.h2" +#line 5058 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5053 "reflect.h2" +#line 5062 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5057 "reflect.h2" +#line 5066 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5061 "reflect.h2" +#line 5070 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5065 "reflect.h2" +#line 5074 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5070 "reflect.h2" +#line 5079 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8858,7 +8869,7 @@ auto i{0}; { auto i{0}; -#line 5077 "reflect.h2" +#line 5086 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8873,7 +8884,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5090 "reflect.h2" +#line 5099 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8886,31 +8897,31 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5102 "reflect.h2" +#line 5111 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5119 "reflect.h2" +#line 5128 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5122 "reflect.h2" +#line 5131 "reflect.h2" } -#line 5124 "reflect.h2" +#line 5133 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5129 "reflect.h2" +#line 5138 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); - diff = " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": ("; + diff = " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": ("; // 1. Generate the modified signature // a) Parameters @@ -8919,14 +8930,14 @@ auto i{0}; std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; if ("this" == name) { - auto ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), std::string(CPP2_UFCS(name)(decl)))}; + auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), std::string(CPP2_UFCS(name)(decl)))}; diff += "" + cpp2::to_string(name) + ", "; - diff += "" + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(cpp2::move(ad_type)) + ", "; + diff += "" + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(cpp2::move(fwd_ad_type)) + ", "; } else { auto type {CPP2_UFCS(get_declaration)(param).type()}; diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "; - diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "; + diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type)); } @@ -8940,10 +8951,10 @@ auto i{0}; // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if (CPP2_UFCS(has_deduced_return_type)(f)) { // TODO: Take care of initialization order error. - diff += "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ", "; + diff += "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ", "; } else { - diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "; + diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "; } } else { @@ -8951,7 +8962,7 @@ auto i{0}; auto name {CPP2_UFCS(get_declaration)(param).name()}; auto type {CPP2_UFCS(get_declaration)(param).type()}; diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "; + diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + ""); } @@ -8966,10 +8977,10 @@ auto i{0}; return ; } -#line 5189 "reflect.h2" +#line 5198 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5192 "reflect.h2" +#line 5201 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8986,10 +8997,10 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5209 "reflect.h2" +#line 5218 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ - std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + ""}; - std::string ad_type {CPP2_UFCS(get_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; + std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; + std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; std::string ad_init {""}; if (CPP2_UFCS(has_initializer)(o)) { @@ -9000,7 +9011,7 @@ auto i{0}; ad_init = " = " + cpp2::move(ad).fwd_expr; } - diff = "" + cpp2::to_string(cpp2::move(ad_name)) + " : " + cpp2::to_string(cpp2::move(ad_type)) + cpp2::to_string(cpp2::move(ad_init)) + ";"; + diff = "" + cpp2::to_string(cpp2::move(ad_name)) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(ad_init)) + ";"; if (is_type_context) { @@ -9014,7 +9025,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5237 "reflect.h2" +#line 5246 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9029,7 +9040,7 @@ auto i{0}; CPP2_UFCS(pop_stack)((*cpp2::impl::assert_not_null(ctx))); if (!(CPP2_UFCS(empty)(ad.diff_ad_type))) { - diff = "" + cpp2::to_string(CPP2_UFCS(name)(t)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).suffix) + " : type = {\n"; + diff = "" + cpp2::to_string(CPP2_UFCS(name)(t)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : type = {\n"; diff += "" + cpp2::to_string(cpp2::move(ad).diff_ad_type) + ""; diff += "}"; @@ -9038,53 +9049,64 @@ auto i{0}; } } -#line 5261 "reflect.h2" +#line 5270 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5266 "reflect.h2" +#line 5275 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5272 "reflect.h2" +#line 5281 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { std::string_view constexpr suffix_token{ "suffix=" }; + std::string_view constexpr rws_suffix_token{ "rws_suffix=" }; std::string_view constexpr order_token{ "order=" }; + std::string_view constexpr reverse_token{ "reverse" }; auto args {CPP2_UFCS(get_arguments)(t)}; std::string suffix {"_d"}; + std::string rws_suffix {"_b"}; int order {1}; + bool reverse {false}; for ( auto const& arg_str : cpp2::move(args) ) { if (CPP2_UFCS(starts_with)(arg_str, "\"") && CPP2_UFCS(ends_with)(arg_str, "\"")) { auto arg {CPP2_UFCS(substr)(arg_str, 1, CPP2_UFCS(ssize)(arg_str) - 2)}; if (CPP2_UFCS(starts_with)(arg, suffix_token)) { - suffix = CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(suffix_token)); + suffix = CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(suffix_token)); + continue; + } + else {if (CPP2_UFCS(starts_with)(arg, rws_suffix_token)) { + suffix = CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(rws_suffix_token)); continue; } - if (CPP2_UFCS(starts_with)(arg, order_token)) { + else {if (CPP2_UFCS(starts_with)(arg, order_token)) { if (!(string_util::string_to_int(CPP2_UFCS(substr)(arg, CPP2_UFCS(size)(order_token)), order))) { CPP2_UFCS(error)(t, "AD: Could not parse derivative order: " + cpp2::to_string(CPP2_UFCS(substr)(cpp2::move(arg), CPP2_UFCS(size)(order_token))) + ""); return ; } continue; } + else {if (cpp2::move(arg) == reverse_token) { + reverse = true; + continue; + }}}} } CPP2_UFCS(error)(t, "AD: Unknown argument: " + cpp2::to_string(arg_str) + ""); return ; } - autodiff_context ad_ctx {}; - ad_ctx.suffix = cpp2::move(suffix); - CPP2_UFCS(set_order)(ad_ctx, order); + autodiff_context ad_ctx {order, cpp2::move(reverse)}; + ad_ctx.fwd_suffix = cpp2::move(suffix); + ad_ctx.rws_suffix = cpp2::move(rws_suffix); -#line 5308 "reflect.h2" if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { auto p {CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))}; CPP2_UFCS(create_namespace_stack)(ad_ctx, p); @@ -9213,7 +9235,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5346 "reflect.h2" +#line 5366 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9229,11 +9251,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5362 "reflect.h2" +#line 5382 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5366 "reflect.h2" +#line 5386 "reflect.h2" // mod: i // mod: m // mod: s @@ -9241,116 +9263,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5375 "reflect.h2" +#line 5395 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5384 "reflect.h2" +#line 5404 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5386 "reflect.h2" +#line 5406 "reflect.h2" } -#line 5388 "reflect.h2" +#line 5408 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5390 "reflect.h2" +#line 5410 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5396 "reflect.h2" +#line 5416 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5397 "reflect.h2" +#line 5417 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5398 "reflect.h2" +#line 5418 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5413 "reflect.h2" +#line 5433 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5416 "reflect.h2" +#line 5436 "reflect.h2" } -#line 5418 "reflect.h2" +#line 5438 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5422 "reflect.h2" +#line 5442 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5434 "reflect.h2" +#line 5454 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5437 "reflect.h2" +#line 5457 "reflect.h2" } -#line 5439 "reflect.h2" +#line 5459 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5443 "reflect.h2" +#line 5463 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5453 "reflect.h2" +#line 5473 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5455 "reflect.h2" +#line 5475 "reflect.h2" } -#line 5457 "reflect.h2" +#line 5477 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5461 "reflect.h2" +#line 5481 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5473 "reflect.h2" +#line 5493 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5476 "reflect.h2" +#line 5496 "reflect.h2" } -#line 5478 "reflect.h2" +#line 5498 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5484 "reflect.h2" +#line 5504 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5490 "reflect.h2" +#line 5510 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9359,7 +9381,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5498 "reflect.h2" +#line 5518 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9375,7 +9397,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5526 "reflect.h2" +#line 5546 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9383,14 +9405,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5534 "reflect.h2" +#line 5554 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5541 "reflect.h2" +#line 5561 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9402,15 +9424,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5553 "reflect.h2" +#line 5573 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5558 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5562 "reflect.h2" +#line 5582 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9431,7 +9453,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5588 "reflect.h2" +#line 5608 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9440,20 +9462,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5597 "reflect.h2" +#line 5617 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5603 "reflect.h2" +#line 5623 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5610 "reflect.h2" +#line 5630 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9468,16 +9490,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5640 "reflect.h2" +#line 5660 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5644 "reflect.h2" +#line 5664 "reflect.h2" } -#line 5650 "reflect.h2" +#line 5670 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9487,7 +9509,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5660 "reflect.h2" +#line 5680 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9495,17 +9517,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5667 "reflect.h2" +#line 5687 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5671 "reflect.h2" +#line 5691 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5678 "reflect.h2" +#line 5698 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9515,7 +9537,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5687 "reflect.h2" +#line 5707 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9523,24 +9545,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5694 "reflect.h2" +#line 5714 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5702 "reflect.h2" +#line 5722 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5706 "reflect.h2" +#line 5726 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5710 "reflect.h2" +#line 5730 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9552,22 +9574,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5721 "reflect.h2" +#line 5741 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5727 "reflect.h2" +#line 5747 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5731 "reflect.h2" +#line 5751 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5735 "reflect.h2" +#line 5755 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9575,7 +9597,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5742 "reflect.h2" +#line 5762 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9587,10 +9609,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5755 "reflect.h2" +#line 5775 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5758 "reflect.h2" +#line 5778 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9630,7 +9652,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5798 "reflect.h2" +#line 5818 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9642,14 +9664,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5809 "reflect.h2" +#line 5829 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5810 "reflect.h2" +#line 5830 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5811 "reflect.h2" +#line 5831 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5813 "reflect.h2" +#line 5833 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9659,10 +9681,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5822 "reflect.h2" +#line 5842 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5824 "reflect.h2" +#line 5844 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9684,14 +9706,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5845 "reflect.h2" +#line 5865 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5846 "reflect.h2" +#line 5866 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5847 "reflect.h2" +#line 5867 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5849 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9705,7 +9727,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5862 "reflect.h2" +#line 5882 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9727,7 +9749,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5883 "reflect.h2" +#line 5903 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9738,12 +9760,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5893 "reflect.h2" +#line 5913 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5894 "reflect.h2" +#line 5914 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5899 "reflect.h2" +#line 5919 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9798,7 +9820,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5953 "reflect.h2" +#line 5973 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9838,7 +9860,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5992 "reflect.h2" +#line 6012 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9854,21 +9876,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6009 "reflect.h2" +#line 6029 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6010 "reflect.h2" +#line 6030 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6011 "reflect.h2" +#line 6031 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6013 "reflect.h2" +#line 6033 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6028 "reflect.h2" +#line 6048 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9876,7 +9898,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6035 "reflect.h2" +#line 6055 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9886,22 +9908,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6053 "reflect.h2" +#line 6073 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6058 "reflect.h2" +#line 6078 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6064 "reflect.h2" +#line 6084 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6070 "reflect.h2" +#line 6090 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9910,7 +9932,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6078 "reflect.h2" +#line 6098 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9922,7 +9944,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6089 "reflect.h2" +#line 6109 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9930,7 +9952,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6096 "reflect.h2" +#line 6116 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9951,7 +9973,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6117 "reflect.h2" +#line 6137 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9961,7 +9983,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6127 "reflect.h2" +#line 6147 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -9984,33 +10006,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6151 "reflect.h2" +#line 6171 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6157 "reflect.h2" +#line 6177 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6161 "reflect.h2" +#line 6181 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6167 "reflect.h2" +#line 6187 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6175 "reflect.h2" +#line 6195 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10019,7 +10041,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6183 "reflect.h2" +#line 6203 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10028,22 +10050,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6193 "reflect.h2" +#line 6213 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6197 "reflect.h2" +#line 6217 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6201 "reflect.h2" +#line 6221 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6205 "reflect.h2" +#line 6225 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10067,18 +10089,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6230 "reflect.h2" +#line 6250 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6245 "reflect.h2" +#line 6265 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6247 "reflect.h2" +#line 6267 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10089,15 +10111,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6262 "reflect.h2" +#line 6282 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6265 "reflect.h2" +#line 6285 "reflect.h2" } -#line 6267 "reflect.h2" +#line 6287 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10115,7 +10137,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6284 "reflect.h2" +#line 6304 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10123,7 +10145,7 @@ generation_function_context::generation_function_context(){} } } -#line 6291 "reflect.h2" +#line 6311 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10137,7 +10159,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6304 "reflect.h2" +#line 6324 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10153,14 +10175,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6325 "reflect.h2" +#line 6345 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6327 "reflect.h2" +#line 6347 "reflect.h2" } -#line 6329 "reflect.h2" +#line 6349 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10169,11 +10191,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6344 "reflect.h2" +#line 6364 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6346 "reflect.h2" +#line 6366 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10181,7 +10203,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6353 "reflect.h2" +#line 6373 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10190,37 +10212,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6361 "reflect.h2" +#line 6381 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6375 "reflect.h2" +#line 6395 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6379 "reflect.h2" +#line 6399 "reflect.h2" } -#line 6381 "reflect.h2" +#line 6401 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6385 "reflect.h2" +#line 6405 "reflect.h2" } -#line 6387 "reflect.h2" +#line 6407 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6391 "reflect.h2" +#line 6411 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10229,14 +10251,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6397 "reflect.h2" +#line 6417 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6402 "reflect.h2" +#line 6422 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10249,7 +10271,7 @@ size_t i{0}; } } -#line 6414 "reflect.h2" +#line 6434 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10271,7 +10293,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6435 "reflect.h2" +#line 6455 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10290,7 +10312,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6453 "reflect.h2" +#line 6473 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10306,14 +10328,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6468 "reflect.h2" +#line 6488 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6474 "reflect.h2" +#line 6494 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10321,19 +10343,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6491 "reflect.h2" +#line 6511 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6492 "reflect.h2" +#line 6512 "reflect.h2" { -#line 6497 "reflect.h2" +#line 6517 "reflect.h2" } -#line 6500 "reflect.h2" +#line 6520 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10459,7 +10481,7 @@ size_t i{0}; ); } -#line 6625 "reflect.h2" +#line 6645 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10469,13 +10491,13 @@ size_t i{0}; ); } -#line 6634 "reflect.h2" +#line 6654 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6639 "reflect.h2" +#line 6659 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10486,12 +10508,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6651 "reflect.h2" +#line 6671 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6656 "reflect.h2" +#line 6676 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10525,7 +10547,7 @@ size_t i{0}; } -#line 6692 "reflect.h2" +#line 6712 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10534,19 +10556,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6715 "reflect.h2" +#line 6735 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6716 "reflect.h2" +#line 6736 "reflect.h2" { -#line 6721 "reflect.h2" +#line 6741 "reflect.h2" } -#line 6723 "reflect.h2" +#line 6743 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10648,19 +10670,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6824 "reflect.h2" +#line 6844 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6828 "reflect.h2" +#line 6848 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6852 "reflect.h2" +#line 6872 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10679,7 +10701,7 @@ size_t i{0}; return r; } -#line 6870 "reflect.h2" +#line 6890 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10694,7 +10716,7 @@ size_t i{0}; return r; } -#line 6884 "reflect.h2" +#line 6904 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10854,7 +10876,7 @@ size_t i{0}; } } -#line 7043 "reflect.h2" +#line 7063 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10863,7 +10885,7 @@ size_t i{0}; return r; } -#line 7051 "reflect.h2" +#line 7071 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10882,7 +10904,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7069 "reflect.h2" +#line 7089 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10914,7 +10936,7 @@ size_t i{0}; } } -#line 7100 "reflect.h2" +#line 7120 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10925,7 +10947,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7112 "reflect.h2" +#line 7132 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10964,7 +10986,7 @@ size_t i{0}; return r; } -#line 7153 "reflect.h2" +#line 7173 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -10982,7 +11004,7 @@ size_t i{0}; }} } -#line 7173 "reflect.h2" +#line 7193 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -10996,16 +11018,16 @@ size_t i{0}; } } -#line 7199 "reflect.h2" +#line 7219 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7202 "reflect.h2" +#line 7222 "reflect.h2" } -#line 7204 "reflect.h2" +#line 7224 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11017,7 +11039,7 @@ size_t i{0}; } } -#line 7215 "reflect.h2" +#line 7235 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11025,14 +11047,14 @@ size_t i{0}; return r; } -#line 7222 "reflect.h2" +#line 7242 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7230 "reflect.h2" +#line 7250 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11058,7 +11080,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7258 "reflect.h2" +#line 7278 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11084,11 +11106,11 @@ size_t i{0}; return r; } -#line 7295 "reflect.h2" +#line 7315 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7297 "reflect.h2" +#line 7317 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11162,7 +11184,7 @@ size_t i{0}; return nullptr; } -#line 7370 "reflect.h2" +#line 7390 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11175,7 +11197,7 @@ size_t i{0}; }} } -#line 7382 "reflect.h2" +#line 7402 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11189,7 +11211,7 @@ size_t i{0}; }} } -#line 7395 "reflect.h2" +#line 7415 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11209,7 +11231,7 @@ size_t i{0}; return r; } -#line 7414 "reflect.h2" +#line 7434 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11220,7 +11242,7 @@ size_t i{0}; return r; } -#line 7424 "reflect.h2" +#line 7444 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11232,14 +11254,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7435 "reflect.h2" +#line 7455 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7447 "reflect.h2" +#line 7467 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11263,7 +11285,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7471 "reflect.h2" +#line 7491 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11273,7 +11295,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7483 "reflect.h2" +#line 7503 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11289,7 +11311,7 @@ size_t i{0}; } } -#line 7503 "reflect.h2" +#line 7523 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11307,15 +11329,15 @@ size_t i{0}; }} } -#line 7539 "reflect.h2" +#line 7559 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7542 "reflect.h2" +#line 7562 "reflect.h2" } -#line 7544 "reflect.h2" +#line 7564 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11351,7 +11373,7 @@ size_t i{0}; return source; } -#line 7579 "reflect.h2" +#line 7599 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11367,7 +11389,7 @@ size_t i{0}; } } -#line 7595 "reflect.h2" +#line 7615 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11376,7 +11398,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11431,7 +11453,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7664 "reflect.h2" +#line 7684 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11553,7 +11575,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7786 "reflect.h2" +#line 7806 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 7a752349a..5b4c022fb 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4083,15 +4083,35 @@ autodiff_context: type = { "_od_.push_back(_ad1_);") ); - public suffix: std::string = "_d"; - private order: int = 1; + public fwd_suffix : std::string = "_d"; + public rws_suffix : std::string = "_b"; + private order : int = 1; + public reverse: bool = false; // Members depending on order - public ad_type: std::string = "double"; + public fwd_ad_type: std::string = "double"; + public rws_ad_type: std::string = "double"; public declaration_map : std::map> = (); public declaration_stack: std::vector = (); + operator=:(out this) = {} + operator=:(out this, order_: int, reverse_: bool) = { + order = order_; + reverse = reverse_; + + if 1 != order { + if reverse { + fwd_ad_type = "cpp2::taylor"; + rws_ad_type = "cpp2::taylor"; + } + else { + fwd_ad_type = "cpp2::taylor"; + } + } + + } + add_variable_declaration: (inout this, name: std::string, type: std::string, is_member: bool = false) = { declaration_stack.back().declared_variables_stack.back().push_back(autodiff_declared_variable(name, type, is_member)); } @@ -4113,17 +4133,6 @@ autodiff_context: type = { _ = declaration_stack.push_back(autodiff_declaration_stack_item(full_name, t)); } - set_order : (inout this, new_order: int) = { - order = new_order; - - if 1 == order { - ad_type = "double"; - } - else { - ad_type = "cpp2::taylor"; - } - } - is_taylor: (this) = order != 1; gen_temporary : (inout this) -> std::string = { @@ -4131,7 +4140,7 @@ autodiff_context: type = { return "temp_(temporary_count)$"; } - get_ad_type: (inout this, type: std::string) -> std::string = { + get_fwd_ad_type: (inout this, type: std::string) -> std::string = { type_d := type; if "double" != type { @@ -4141,12 +4150,12 @@ autodiff_context: type = { add_for_differentiation(type_decls[0]); // Add the AD suffix to the type - type_d += suffix; + type_d += fwd_suffix; } } // Replace with AD type for the AD order. - return string_util::replace_all(type_d, "double", ad_type); + return string_util::replace_all(type_d, "double", fwd_ad_type); } lookup_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { @@ -4355,7 +4364,7 @@ autodiff_expression_handler: type = { return lhs; } else { - return lhs + ctx*.suffix; + return lhs + ctx*.fwd_suffix; } } @@ -4374,11 +4383,11 @@ autodiff_expression_handler: type = { diff += "(lhs)$ : (type)$ = (rhs)$;\n"; } gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string) - = gen_declaration(lhs, lhs_d, rhs, rhs_d, type, ctx*.get_ad_type(type)); + = gen_declaration(lhs, lhs_d, rhs, rhs_d, type, ctx*.get_fwd_ad_type(type)); gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, type: std::string) - = gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, ctx*.get_ad_type(type)); + = gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, ctx*.get_fwd_ad_type(type)); gen_declaration: (inout this, lhs: std::string, type: std::string) - = gen_declaration(lhs, lhs + ctx*.suffix, primal_expr, fwd_expr, type, ctx*.get_ad_type(type)); + = gen_declaration(lhs, lhs + ctx*.fwd_suffix, primal_expr, fwd_expr, type, ctx*.get_fwd_ad_type(type)); @@ -4399,11 +4408,11 @@ autodiff_expression_handler: type = { handle_expression_term :(inout this, term) -> primal_fwd_name = { if term.is_identifier() { primal := term.to_string(); - fwd := primal + ctx*.suffix; + fwd := primal + ctx*.fwd_suffix; decl := ctx*.lookup_variable_declaration(primal); if decl.is_member { - fwd = "this(ctx*.suffix)$." + fwd; + fwd = "this(ctx*.fwd_suffix)$." + fwd; } return (primal, fwd); } @@ -4427,7 +4436,7 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - r : primal_fwd_name = (t, t + ctx*.suffix); // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + r : primal_fwd_name = (t, t + ctx*.fwd_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) _ = t; return r; } @@ -4441,7 +4450,7 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - r : primal_fwd_name = (t, t + ctx*.suffix); // TODO: Check why on return (t, t + ctx*.suffix) the primal is initialized empty. Probably because of the move(t) + r : primal_fwd_name = (t, t + ctx*.fwd_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) _ = t; return r; } @@ -4479,7 +4488,7 @@ autodiff_expression_handler: type = { if 1 != terms.ssize() { object = primary.to_string(); - object_d = primary.to_string() + ctx*.suffix; + object_d = primary.to_string() + ctx*.fwd_suffix; } else { function_name = primary.to_string(); @@ -4496,7 +4505,7 @@ autodiff_expression_handler: type = { } else { object += "." + name; - object_d += "." + name + ctx*.suffix; + object_d += "." + name + ctx*.fwd_suffix; } } else if term.get_op() == "(" { @@ -4529,7 +4538,7 @@ autodiff_expression_handler: type = { if !object.empty() { // Prepend object call diff += "(object)$."; } - diff += "(function_name)$(ctx*.suffix)$("; + diff += "(function_name)$(ctx*.fwd_suffix)$("; if !object.empty() { // Add this_d argument. diff += "(object_d)$, "; } @@ -4582,7 +4591,7 @@ autodiff_expression_handler: type = { } } - ret_name_d : std::string = ret_name + ctx*.suffix; + ret_name_d : std::string = ret_name + ctx*.fwd_suffix; primal_expr = "(ret_temp)$.(ret_name)$"; fwd_expr = "(ret_temp)$.(ret_name_d)$"; @@ -4742,7 +4751,7 @@ autodiff_expression_handler: type = { else { // Temporary t := ctx*.gen_temporary(); - t_d := t + ctx*.suffix; + t_d := t + ctx*.fwd_suffix; gen_declaration(t, t_d, primal, fwd, "", ""); arg_a = t; @@ -4799,11 +4808,11 @@ autodiff_expression_handler: type = { primary : = postfix.get_primary_expression(); obj_access : std::string = primary.to_string(); - obj_access_d : std::string = obj_access + ctx*.suffix; + obj_access_d : std::string = obj_access + ctx*.fwd_suffix; for terms do (term) { obj_access += term.get_op() + term.get_id_expression().to_string(); - obj_access_d += term.get_op() + term.get_id_expression().to_string() + ctx*.suffix; + obj_access_d += term.get_op() + term.get_id_expression().to_string() + ctx*.fwd_suffix; } primal_expr = obj_access; @@ -4819,7 +4828,7 @@ autodiff_expression_handler: type = { decl := ctx*.lookup_variable_declaration(primal_expr); if decl.is_member { - fwd_expr = "this(ctx*.suffix)$." + fwd_expr; + fwd_expr = "this(ctx*.fwd_suffix)$." + fwd_expr; } } else if primary.is_expression_list() { @@ -4871,7 +4880,7 @@ autodiff_stmt_handler: type = { lhs : std::string = o.name(); type : = o.type(); - ad_type : = ctx*.get_ad_type(type); + fwd_ad_type : = ctx*.get_fwd_ad_type(type); prim_init: std::string = ""; fwd_init : std::string = ""; @@ -4886,10 +4895,10 @@ autodiff_stmt_handler: type = { if type == "_" && ad.fwd_expr == "()" { // Special handling for auto initialization from a literal. - fwd_init = " = " + ctx*.get_ad_type("double") + "()"; + fwd_init = " = " + ctx*.get_fwd_ad_type("double") + "()"; } } - diff += "(lhs)$(ctx*.suffix)$ : (ad_type)$(fwd_init)$;\n"; + diff += "(lhs)$(ctx*.fwd_suffix)$ : (fwd_ad_type)$(fwd_init)$;\n"; diff += "(lhs)$ : (type)$(prim_init)$;\n"; ctx*.add_variable_declaration(lhs, type); @@ -4968,7 +4977,7 @@ autodiff_stmt_handler: type = { param := stmt.get_for_parameter(); param_style := to_string_view(param.get_passing_style()); param_decl := param.get_declaration(); - diff += "(copy (param_decl.name())$_d_iter := (range)$(ctx*.suffix)$.begin())\n"; + diff += "(copy (param_decl.name())$_d_iter := (range)$(ctx*.fwd_suffix)$.begin())\n"; diff += "for (range)$ next ("; if stmt.has_next() { // TODO: Assumption is here that nothing is in the next expression @@ -4976,7 +4985,7 @@ autodiff_stmt_handler: type = { } diff += "(param_decl.name())$_d_iter++"; diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; - diff += "((param_style)$ (param_decl.name())$(ctx*.suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; + diff += "((param_style)$ (param_decl.name())$(ctx*.fwd_suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; ctx*.add_variable_declaration("(param_decl.name())$", "(param_decl.type())$"); // TODO: Handle loop/compound context variable declarations. @@ -5129,7 +5138,7 @@ autodiff_declaration_handler: type = { traverse: (override inout this, f: meta::function_declaration) = { ctx*.enter_function(); - diff = " (f.name())$(ctx*.suffix)$: ("; + diff = " (f.name())$(ctx*.fwd_suffix)$: ("; // 1. Generate the modified signature // a) Parameters @@ -5138,14 +5147,14 @@ autodiff_declaration_handler: type = { name : std::string = param.get_declaration().name(); if "this" == name{ - ad_type := ctx*.get_ad_type(std::string(decl.name())); + fwd_ad_type := ctx*.get_fwd_ad_type(std::string(decl.name())); diff += "(name)$, "; - diff += "(name)$(ctx*.suffix)$: (ad_type)$, "; + diff += "(name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "; } else { type := param.get_declaration().type(); diff += "(name)$ : (type)$, "; - diff += "(name)$(ctx*.suffix)$ : (ctx*.get_ad_type(type))$, "; + diff += "(name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "; ctx*.add_variable_declaration(name, type); } @@ -5159,10 +5168,10 @@ autodiff_declaration_handler: type = { // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if f.has_deduced_return_type() { // TODO: Take care of initialization order error. - diff += "r, r(ctx*.suffix)$, "; + diff += "r, r(ctx*.fwd_suffix)$, "; } else { - diff += "r: (f.get_unnamed_return_type())$ = (), r(ctx*.suffix)$: (ctx*.get_ad_type(f.get_unnamed_return_type()))$ = (), "; + diff += "r: (f.get_unnamed_return_type())$ = (), r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "; } } else { @@ -5170,7 +5179,7 @@ autodiff_declaration_handler: type = { name := param.get_declaration().name(); type := param.get_declaration().type(); diff += "(name)$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(name)$(ctx*.suffix)$ : (ctx*.get_ad_type(type))$ = 0.0, "; + diff += "(name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "; ctx*.add_variable_declaration("(name)$", "(type)$"); } @@ -5207,8 +5216,8 @@ autodiff_declaration_handler: type = { traverse: (override inout this, o: meta::object_declaration) = { - ad_name : std::string = "(o.name())$(ctx*.suffix)$"; - ad_type : std::string = ctx*.get_ad_type(o.type()); + ad_name : std::string = "(o.name())$(ctx*.fwd_suffix)$"; + fwd_ad_type : std::string = ctx*.get_fwd_ad_type(o.type()); ad_init : std::string = ""; if o.has_initializer() { @@ -5219,7 +5228,7 @@ autodiff_declaration_handler: type = { ad_init = " = " +ad.fwd_expr; } - diff = "(ad_name)$ : (ad_type)$(ad_init)$;"; + diff = "(ad_name)$ : (fwd_ad_type)$(ad_init)$;"; if is_type_context { @@ -5248,7 +5257,7 @@ autodiff_declaration_handler: type = { ctx*.pop_stack(); if !ad.diff_ad_type.empty() { - diff = "(t.name())$(ctx*.suffix)$ : type = {\n"; + diff = "(t.name())$(ctx*.fwd_suffix)$ : type = {\n"; diff += "(ad.diff_ad_type)$"; diff += "}"; @@ -5272,13 +5281,17 @@ autodiff_declaration_handler: type = { autodiff: (inout t: meta::type_declaration) = { - suffix_token : std::string_view == "suffix="; - order_token : std::string_view == "order="; + suffix_token : std::string_view == "suffix="; + rws_suffix_token : std::string_view == "rws_suffix="; + order_token : std::string_view == "order="; + reverse_token : std::string_view == "reverse"; args := t.get_arguments(); - suffix : std::string = "_d"; - order : int = 1; + suffix : std::string = "_d"; + rws_suffix: std::string = "_b"; + order : int = 1; + reverse : bool = false; for args do (arg_str) { if arg_str.starts_with("\"") && arg_str.ends_with("\"") { arg := arg_str.substr(1, arg_str.ssize() - 2); @@ -5287,23 +5300,30 @@ autodiff: (inout t: meta::type_declaration) = suffix = arg.substr(suffix_token.size()); continue; } - if arg.starts_with(order_token) { + else if arg.starts_with(rws_suffix_token) { + suffix = arg.substr(rws_suffix_token.size()); + continue; + } + else if arg.starts_with(order_token) { if !string_util::string_to_int(arg.substr(order_token.size()), order) { t.error("AD: Could not parse derivative order: (arg.substr(order_token.size()))$"); return; } continue; } + else if arg == reverse_token { + reverse = true; + continue; + } } t.error("AD: Unknown argument: (arg_str)$"); return; } - ad_ctx: autodiff_context = (); - ad_ctx.suffix = suffix; - ad_ctx.set_order(order); - + ad_ctx: autodiff_context = (order, reverse); + ad_ctx.fwd_suffix = suffix; + ad_ctx.rws_suffix = rws_suffix; if t.parent_is_nonglobal_namespace() { p := t.get_parent().as_nonglobal_namespace(); From 50bea33a4e07f10bec49e12a9086b6250406409c Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 22 Aug 2025 10:56:02 +0200 Subject: [PATCH 39/54] Refactor of diff string to structure. Currently placeholder that defaults to the forward derivatives. --- include/cpp2taylor.h | 135 +++-- source/reflect.h | 1184 ++++++++++++++++++++++-------------------- source/reflect.h2 | 51 +- 3 files changed, 762 insertions(+), 608 deletions(-) diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index e07cb3171..5ba6f124f 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -16,7 +16,7 @@ namespace cpp2 { template class taylor; -#line 225 "cpp2taylor.h2" +#line 242 "cpp2taylor.h2" } @@ -72,41 +72,49 @@ template class taylor { public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; #line 66 "cpp2taylor.h2" + // Overload for simple handling of prefix +. + public: [[nodiscard]] auto operator+() const& -> taylor; + +#line 71 "cpp2taylor.h2" + // Overload for simple handling of prefix -. + public: [[nodiscard]] auto operator-() const& -> taylor; + +#line 83 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 77 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 88 "cpp2taylor.h2" +#line 105 "cpp2taylor.h2" public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 101 "cpp2taylor.h2" +#line 118 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 119 "cpp2taylor.h2" +#line 136 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; -#line 138 "cpp2taylor.h2" +#line 155 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; -#line 157 "cpp2taylor.h2" +#line 174 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; -#line 176 "cpp2taylor.h2" +#line 193 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; -#line 193 "cpp2taylor.h2" +#line 210 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; -#line 203 "cpp2taylor.h2" +#line 220 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; -#line 212 "cpp2taylor.h2" +#line 229 "cpp2taylor.h2" }; template [[nodiscard]] auto to_string(taylor const& o) -> std::string; -#line 225 "cpp2taylor.h2" +#line 242 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H @@ -228,62 +236,83 @@ auto i{2}; return sub(o, 0.0, 0.0); // Primal values are not required. } -#line 66 "cpp2taylor.h2" +#line 67 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator+() const& -> taylor{ + return (*this); + } + +#line 72 "cpp2taylor.h2" + template [[nodiscard]] auto taylor::operator-() const& -> taylor{ + taylor r {}; +{ +auto k{1}; + +#line 76 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { + CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = -CPP2_ASSERT_IN_BOUNDS(v, k - 1); + } +} + +#line 80 "cpp2taylor.h2" + return r; + } + +#line 83 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 70 "cpp2taylor.h2" +#line 87 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } -#line 74 "cpp2taylor.h2" +#line 91 "cpp2taylor.h2" return r; } -#line 77 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 81 "cpp2taylor.h2" +#line 98 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } -#line 85 "cpp2taylor.h2" +#line 102 "cpp2taylor.h2" return r; } -#line 88 "cpp2taylor.h2" +#line 105 "cpp2taylor.h2" template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 92 "cpp2taylor.h2" +#line 109 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{0}; -#line 94 "cpp2taylor.h2" +#line 111 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } -#line 97 "cpp2taylor.h2" +#line 114 "cpp2taylor.h2" } } -#line 98 "cpp2taylor.h2" +#line 115 "cpp2taylor.h2" return r; } -#line 101 "cpp2taylor.h2" +#line 118 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; @@ -292,26 +321,26 @@ auto j{0}; { auto k{1}; -#line 108 "cpp2taylor.h2" +#line 125 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; -#line 111 "cpp2taylor.h2" +#line 128 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } -#line 114 "cpp2taylor.h2" +#line 131 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 116 "cpp2taylor.h2" +#line 133 "cpp2taylor.h2" return r; } -#line 119 "cpp2taylor.h2" +#line 136 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; @@ -320,27 +349,27 @@ auto j{0}; { auto k{1}; -#line 126 "cpp2taylor.h2" +#line 143 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; -#line 129 "cpp2taylor.h2" +#line 146 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } -#line 132 "cpp2taylor.h2" +#line 149 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 135 "cpp2taylor.h2" +#line 152 "cpp2taylor.h2" return r; } -#line 138 "cpp2taylor.h2" +#line 155 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; @@ -349,27 +378,27 @@ auto j{1}; { auto k{1}; -#line 145 "cpp2taylor.h2" +#line 162 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; -#line 148 "cpp2taylor.h2" +#line 165 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } -#line 151 "cpp2taylor.h2" +#line 168 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } -#line 154 "cpp2taylor.h2" +#line 171 "cpp2taylor.h2" return r; } -#line 157 "cpp2taylor.h2" +#line 174 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; @@ -378,52 +407,52 @@ auto j{1}; { auto k{1}; -#line 164 "cpp2taylor.h2" +#line 181 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 166 "cpp2taylor.h2" +#line 183 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } -#line 169 "cpp2taylor.h2" +#line 186 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } -#line 172 "cpp2taylor.h2" +#line 189 "cpp2taylor.h2" return r; } -#line 176 "cpp2taylor.h2" +#line 193 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; -#line 181 "cpp2taylor.h2" +#line 198 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 183 "cpp2taylor.h2" +#line 200 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); } } -#line 187 "cpp2taylor.h2" +#line 204 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } -#line 190 "cpp2taylor.h2" +#line 207 "cpp2taylor.h2" } -#line 193 "cpp2taylor.h2" +#line 210 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -434,7 +463,7 @@ auto j{1}; return r; } -#line 203 "cpp2taylor.h2" +#line 220 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -445,18 +474,18 @@ auto j{1}; return r; } -#line 214 "cpp2taylor.h2" +#line 231 "cpp2taylor.h2" template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ std::string r {"("}; { auto i{1}; -#line 217 "cpp2taylor.h2" +#line 234 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; } } -#line 220 "cpp2taylor.h2" +#line 237 "cpp2taylor.h2" r += " )"; return r; diff --git a/source/reflect.h b/source/reflect.h index 632a33668..aa6fb3d35 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -122,90 +122,94 @@ class autodiff_context; #line 4335 "reflect.h2" +class autodiff_diff_code; + + +#line 4372 "reflect.h2" class autodiff_handler_base; -#line 4349 "reflect.h2" +#line 4388 "reflect.h2" class autodiff_expression_handler; -#line 4856 "reflect.h2" +#line 4895 "reflect.h2" class autodiff_stmt_handler; -#line 5117 "reflect.h2" +#line 5156 "reflect.h2" class autodiff_declaration_handler; -#line 5384 "reflect.h2" +#line 5423 "reflect.h2" class expression_flags; -#line 5400 "reflect.h2" +#line 5439 "reflect.h2" class regex_token; -#line 5427 "reflect.h2" +#line 5466 "reflect.h2" class regex_token_check; -#line 5448 "reflect.h2" +#line 5487 "reflect.h2" class regex_token_code; -#line 5469 "reflect.h2" +#line 5508 "reflect.h2" class regex_token_empty; -#line 5487 "reflect.h2" +#line 5526 "reflect.h2" class regex_token_list; -#line 5539 "reflect.h2" +#line 5578 "reflect.h2" class parse_context_group_state; -#line 5600 "reflect.h2" +#line 5639 "reflect.h2" class parse_context_branch_reset_state; -#line 5643 "reflect.h2" +#line 5682 "reflect.h2" class parse_context; -#line 6044 "reflect.h2" +#line 6083 "reflect.h2" class generation_function_context; -#line 6062 "reflect.h2" +#line 6101 "reflect.h2" class generation_context; -#line 6261 "reflect.h2" +#line 6300 "reflect.h2" class alternative_token; -#line 6276 "reflect.h2" +#line 6315 "reflect.h2" class alternative_token_gen; -#line 6341 "reflect.h2" +#line 6380 "reflect.h2" class any_token; -#line 6358 "reflect.h2" +#line 6397 "reflect.h2" class atomic_group_token; -#line 6388 "reflect.h2" +#line 6427 "reflect.h2" class char_token; -#line 6503 "reflect.h2" +#line 6542 "reflect.h2" class class_token; -#line 6727 "reflect.h2" +#line 6766 "reflect.h2" class group_ref_token; -#line 6864 "reflect.h2" +#line 6903 "reflect.h2" class group_token; -#line 7211 "reflect.h2" +#line 7250 "reflect.h2" class lookahead_lookbehind_token; -#line 7306 "reflect.h2" +#line 7345 "reflect.h2" class range_token; -#line 7463 "reflect.h2" +#line 7502 "reflect.h2" class special_range_token; -#line 7549 "reflect.h2" +#line 7588 "reflect.h2" template class regex_generator; -#line 7806 "reflect.h2" +#line 7845 "reflect.h2" } } @@ -1842,27 +1846,56 @@ struct lookup_special_function_handling_ret { bool m; std::string code_primal; s #line 4333 "reflect.h2" }; +class autodiff_diff_code { + public: autodiff_context* ctx; + + public: std::string fwd {""}; + public: std::string rws {""}; + + public: autodiff_diff_code(autodiff_context* ctx_); +#line 4341 "reflect.h2" + public: auto operator=(autodiff_context* ctx_) -> autodiff_diff_code& ; + +#line 4346 "reflect.h2" + public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; + +#line 4352 "reflect.h2" + public: auto operator+=(cpp2::impl::in v) & -> void; + +#line 4357 "reflect.h2" + public: auto operator+=(cpp2::impl::in v) & -> void; + +#line 4362 "reflect.h2" + public: [[nodiscard]] auto empty() const& -> bool; + public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_diff_code const&) -> void = delete; + + +#line 4365 "reflect.h2" +}; + +#line 4372 "reflect.h2" class autodiff_handler_base { public: autodiff_context* ctx; - public: std::string diff {""}; + public: autodiff_diff_code diff; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4340 "reflect.h2" +#line 4377 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4344 "reflect.h2" +#line 4383 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4347 "reflect.h2" +#line 4386 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4353 "reflect.h2" +#line 4392 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1870,28 +1903,28 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4362 "reflect.h2" +#line 4401 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; -#line 4371 "reflect.h2" +#line 4410 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; -#line 4375 "reflect.h2" +#line 4414 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4381 "reflect.h2" +#line 4420 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; -#line 4385 "reflect.h2" +#line 4424 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4394 "reflect.h2" +#line 4433 "reflect.h2" public: class primal_fwd_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -1899,176 +1932,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_name(); -#line 4397 "reflect.h2" +#line 4436 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4408 "reflect.h2" +#line 4447 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_name; -#line 4459 "reflect.h2" +#line 4498 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4603 "reflect.h2" +#line 4642 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4638 "reflect.h2" +#line 4677 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4642 "reflect.h2" +#line 4681 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4646 "reflect.h2" +#line 4685 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4650 "reflect.h2" +#line 4689 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4654 "reflect.h2" +#line 4693 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4658 "reflect.h2" +#line 4697 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4662 "reflect.h2" +#line 4701 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4666 "reflect.h2" +#line 4705 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4670 "reflect.h2" +#line 4709 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4674 "reflect.h2" +#line 4713 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4678 "reflect.h2" +#line 4717 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4682 "reflect.h2" +#line 4721 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4706 "reflect.h2" +#line 4745 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4763 "reflect.h2" +#line 4802 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4767 "reflect.h2" +#line 4806 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4783 "reflect.h2" +#line 4822 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4823 "reflect.h2" +#line 4862 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4854 "reflect.h2" +#line 4893 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4860 "reflect.h2" +#line 4899 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4869 "reflect.h2" +#line 4908 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4874 "reflect.h2" +#line 4913 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4879 "reflect.h2" +#line 4918 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4908 "reflect.h2" +#line 4947 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4913 "reflect.h2" +#line 4952 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4918 "reflect.h2" +#line 4957 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4923 "reflect.h2" +#line 4962 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4931 "reflect.h2" +#line 4970 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4948 "reflect.h2" +#line 4987 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4998 "reflect.h2" +#line 5037 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5009 "reflect.h2" +#line 5048 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5013 "reflect.h2" +#line 5052 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5026 "reflect.h2" +#line 5065 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5030 "reflect.h2" +#line 5069 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5034 "reflect.h2" +#line 5073 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5038 "reflect.h2" +#line 5077 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5042 "reflect.h2" +#line 5081 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5046 "reflect.h2" +#line 5085 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5050 "reflect.h2" +#line 5089 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5054 "reflect.h2" +#line 5093 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5058 "reflect.h2" +#line 5097 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5062 "reflect.h2" +#line 5101 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5066 "reflect.h2" +#line 5105 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5070 "reflect.h2" +#line 5109 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5074 "reflect.h2" +#line 5113 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5079 "reflect.h2" +#line 5118 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5111 "reflect.h2" +#line 5150 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5115 "reflect.h2" +#line 5154 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5121 "reflect.h2" +#line 5160 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2078,37 +2111,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 5133 "reflect.h2" +#line 5172 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5138 "reflect.h2" +#line 5177 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5218 "reflect.h2" +#line 5257 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5246 "reflect.h2" +#line 5285 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5270 "reflect.h2" +#line 5309 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5275 "reflect.h2" +#line 5314 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5278 "reflect.h2" +#line 5317 "reflect.h2" }; -#line 5281 "reflect.h2" +#line 5320 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5380 "reflect.h2" +#line 5419 "reflect.h2" using error_func = std::function x)>; -#line 5384 "reflect.h2" +#line 5423 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2143,20 +2176,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5392 "reflect.h2" +#line 5431 "reflect.h2" }; -#line 5400 "reflect.h2" +#line 5439 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5408 "reflect.h2" +#line 5447 "reflect.h2" public: explicit regex_token(); -#line 5413 "reflect.h2" +#line 5452 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2168,103 +2201,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5419 "reflect.h2" +#line 5458 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5425 "reflect.h2" +#line 5464 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5431 "reflect.h2" +#line 5470 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5438 "reflect.h2" +#line 5477 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5442 "reflect.h2" +#line 5481 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5443 "reflect.h2" +#line 5482 "reflect.h2" }; -#line 5446 "reflect.h2" +#line 5485 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5452 "reflect.h2" +#line 5491 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5459 "reflect.h2" +#line 5498 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5463 "reflect.h2" +#line 5502 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5464 "reflect.h2" +#line 5503 "reflect.h2" }; -#line 5467 "reflect.h2" +#line 5506 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5473 "reflect.h2" +#line 5512 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5477 "reflect.h2" +#line 5516 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5481 "reflect.h2" +#line 5520 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5482 "reflect.h2" +#line 5521 "reflect.h2" }; -#line 5485 "reflect.h2" +#line 5524 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5491 "reflect.h2" +#line 5530 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5498 "reflect.h2" +#line 5537 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5504 "reflect.h2" +#line 5543 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5510 "reflect.h2" +#line 5549 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5518 "reflect.h2" +#line 5557 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2272,10 +2305,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5530 "reflect.h2" +#line 5569 "reflect.h2" }; -#line 5533 "reflect.h2" +#line 5572 "reflect.h2" // // Parse and generation context. // @@ -2291,33 +2324,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5553 "reflect.h2" +#line 5592 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5560 "reflect.h2" +#line 5599 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5572 "reflect.h2" +#line 5611 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5577 "reflect.h2" +#line 5616 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5581 "reflect.h2" +#line 5620 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5595 "reflect.h2" +#line 5634 "reflect.h2" }; -#line 5598 "reflect.h2" +#line 5637 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2330,25 +2363,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5616 "reflect.h2" +#line 5655 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5622 "reflect.h2" +#line 5661 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5629 "reflect.h2" +#line 5668 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5636 "reflect.h2" +#line 5675 "reflect.h2" }; -#line 5639 "reflect.h2" +#line 5678 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2364,7 +2397,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5655 "reflect.h2" +#line 5694 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2372,64 +2405,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5666 "reflect.h2" +#line 5705 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5679 "reflect.h2" +#line 5718 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5687 "reflect.h2" +#line 5726 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5691 "reflect.h2" +#line 5730 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5695 "reflect.h2" +#line 5734 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5707 "reflect.h2" +#line 5746 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5714 "reflect.h2" +#line 5753 "reflect.h2" public: auto next_alternative() & -> void; -#line 5720 "reflect.h2" +#line 5759 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5726 "reflect.h2" +#line 5765 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5730 "reflect.h2" +#line 5769 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5741 "reflect.h2" +#line 5780 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5745 "reflect.h2" +#line 5784 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5751 "reflect.h2" +#line 5790 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5755 "reflect.h2" +#line 5794 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5762 "reflect.h2" +#line 5801 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5773 "reflect.h2" +#line 5812 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2437,51 +2470,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5817 "reflect.h2" +#line 5856 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5829 "reflect.h2" +#line 5868 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5842 "reflect.h2" +#line 5881 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5865 "reflect.h2" +#line 5904 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5882 "reflect.h2" +#line 5921 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5903 "reflect.h2" +#line 5942 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5913 "reflect.h2" +#line 5952 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5917 "reflect.h2" +#line 5956 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 5973 "reflect.h2" +#line 6012 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6012 "reflect.h2" +#line 6051 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6027 "reflect.h2" +#line 6066 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2493,10 +2526,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6038 "reflect.h2" +#line 6077 "reflect.h2" }; -#line 6041 "reflect.h2" +#line 6080 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2506,16 +2539,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6055 "reflect.h2" +#line 6094 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6058 "reflect.h2" +#line 6097 "reflect.h2" }; -#line 6061 "reflect.h2" +#line 6100 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2535,68 +2568,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6083 "reflect.h2" +#line 6122 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6089 "reflect.h2" +#line 6128 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6098 "reflect.h2" +#line 6137 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6109 "reflect.h2" +#line 6148 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6116 "reflect.h2" +#line 6155 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6136 "reflect.h2" +#line 6175 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6146 "reflect.h2" +#line 6185 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6169 "reflect.h2" +#line 6208 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6177 "reflect.h2" +#line 6216 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6181 "reflect.h2" +#line 6220 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6187 "reflect.h2" +#line 6226 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6193 "reflect.h2" +#line 6232 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6203 "reflect.h2" +#line 6242 "reflect.h2" public: auto finish_context() & -> void; -#line 6211 "reflect.h2" +#line 6250 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6217 "reflect.h2" +#line 6256 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6221 "reflect.h2" +#line 6260 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6225 "reflect.h2" +#line 6264 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6249 "reflect.h2" +#line 6288 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2604,7 +2637,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6255 "reflect.h2" +#line 6294 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2624,27 +2657,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6274 "reflect.h2" +#line 6313 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6280 "reflect.h2" +#line 6319 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6287 "reflect.h2" +#line 6326 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6304 "reflect.h2" +#line 6343 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6311 "reflect.h2" +#line 6350 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6324 "reflect.h2" +#line 6363 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2652,19 +2685,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6336 "reflect.h2" +#line 6375 "reflect.h2" }; -#line 6339 "reflect.h2" +#line 6378 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6345 "reflect.h2" +#line 6384 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6349 "reflect.h2" +#line 6388 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2672,7 +2705,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6354 "reflect.h2" +#line 6393 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2680,17 +2713,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6362 "reflect.h2" +#line 6401 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6373 "reflect.h2" +#line 6412 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6381 "reflect.h2" +#line 6420 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2698,7 +2731,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6384 "reflect.h2" +#line 6423 "reflect.h2" }; // Regex syntax: a @@ -2706,34 +2739,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6392 "reflect.h2" +#line 6431 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6401 "reflect.h2" +#line 6440 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6407 "reflect.h2" +#line 6446 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6411 "reflect.h2" +#line 6450 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6434 "reflect.h2" +#line 6473 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6455 "reflect.h2" +#line 6494 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6473 "reflect.h2" +#line 6512 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6488 "reflect.h2" +#line 6527 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6494 "reflect.h2" +#line 6533 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2741,33 +2774,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6498 "reflect.h2" +#line 6537 "reflect.h2" }; -#line 6501 "reflect.h2" +#line 6540 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6507 "reflect.h2" +#line 6546 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6519 "reflect.h2" +#line 6558 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6645 "reflect.h2" +#line 6684 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6654 "reflect.h2" +#line 6693 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6659 "reflect.h2" +#line 6698 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2775,20 +2808,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6666 "reflect.h2" +#line 6705 "reflect.h2" }; -#line 6669 "reflect.h2" +#line 6708 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6710 "reflect.h2" +#line 6749 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6721 "reflect.h2" +#line 6760 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2798,20 +2831,20 @@ class class_token class group_ref_token : public regex_token { -#line 6731 "reflect.h2" +#line 6770 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6743 "reflect.h2" +#line 6782 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6844 "reflect.h2" +#line 6883 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6848 "reflect.h2" +#line 6887 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2819,10 +2852,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6851 "reflect.h2" +#line 6890 "reflect.h2" }; -#line 6854 "reflect.h2" +#line 6893 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2836,29 +2869,29 @@ class group_ref_token class group_token : public regex_token { -#line 6868 "reflect.h2" +#line 6907 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6890 "reflect.h2" +#line 6929 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6904 "reflect.h2" +#line 6943 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7063 "reflect.h2" +#line 7102 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7071 "reflect.h2" +#line 7110 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7089 "reflect.h2" +#line 7128 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7120 "reflect.h2" +#line 7159 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2867,25 +2900,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7127 "reflect.h2" +#line 7166 "reflect.h2" }; -#line 7130 "reflect.h2" +#line 7169 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7171 "reflect.h2" +#line 7210 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7191 "reflect.h2" +#line 7230 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7207 "reflect.h2" +#line 7246 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2893,20 +2926,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7215 "reflect.h2" +#line 7254 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7224 "reflect.h2" +#line 7263 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7235 "reflect.h2" +#line 7274 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7242 "reflect.h2" +#line 7281 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2914,26 +2947,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7245 "reflect.h2" +#line 7284 "reflect.h2" }; -#line 7248 "reflect.h2" +#line 7287 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7276 "reflect.h2" +#line 7315 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7304 "reflect.h2" +#line 7343 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7310 "reflect.h2" +#line 7349 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2943,22 +2976,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7390 "reflect.h2" +#line 7429 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7402 "reflect.h2" +#line 7441 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7415 "reflect.h2" +#line 7454 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7434 "reflect.h2" +#line 7473 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7444 "reflect.h2" +#line 7483 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7455 "reflect.h2" +#line 7494 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2966,16 +2999,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7458 "reflect.h2" +#line 7497 "reflect.h2" }; -#line 7461 "reflect.h2" +#line 7500 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7467 "reflect.h2" +#line 7506 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -2984,7 +3017,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7497 "reflect.h2" +#line 7536 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -2993,14 +3026,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7519 "reflect.h2" +#line 7558 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7541 "reflect.h2" +#line 7580 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3021,24 +3054,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7564 "reflect.h2" +#line 7603 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7599 "reflect.h2" +#line 7638 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7613 "reflect.h2" +#line 7652 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7625 "reflect.h2" +#line 7664 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7680 "reflect.h2" +#line 7719 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3049,7 +3082,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7806 "reflect.h2" +#line 7845 "reflect.h2" } } @@ -8061,35 +8094,88 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4340 "reflect.h2" - autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) +#line 4341 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4342 "reflect.h2" +#line 4343 "reflect.h2" } -#line 4340 "reflect.h2" +#line 4341 "reflect.h2" + auto autodiff_diff_code::operator=(autodiff_context* ctx_) -> autodiff_diff_code& { + ctx = ctx_; + fwd = ""; + rws = ""; + return *this; + +#line 4343 "reflect.h2" + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +#line 4346 "reflect.h2" + auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { + ctx = ctx; + fwd = v; + rws = ""; + return *this; + +#line 4349 "reflect.h2" + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +#line 4352 "reflect.h2" + auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ + fwd += v; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +#line 4357 "reflect.h2" + auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ + fwd += v.fwd; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +#line 4362 "reflect.h2" + [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ + return CPP2_UFCS(empty)(fwd); + } + +#line 4367 "reflect.h2" +// // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +// to_string: (v: autodiff_diff_code) -> std::string = { +// return v.fwd; +// } + +#line 4377 "reflect.h2" + autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) + : ctx{ ctx_ } + , diff{ ctx }{ + +#line 4380 "reflect.h2" + } +#line 4377 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; - diff = ""; + diff = ctx; return *this; -#line 4342 "reflect.h2" +#line 4380 "reflect.h2" } -#line 4344 "reflect.h2" + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +#line 4383 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ - diff += o.diff; + diff += o.diff.fwd; } -#line 4358 "reflect.h2" +#line 4397 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4360 "reflect.h2" +#line 4399 "reflect.h2" } -#line 4362 "reflect.h2" +#line 4401 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8099,30 +8185,30 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4371 "reflect.h2" +#line 4410 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4375 "reflect.h2" +#line 4414 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } -#line 4377 "reflect.h2" +#line 4416 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } -#line 4381 "reflect.h2" +#line 4420 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4385 "reflect.h2" +#line 4424 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4387 "reflect.h2" +#line 4426 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4389 "reflect.h2" +#line 4428 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } @@ -8132,7 +8218,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8142,7 +8228,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} return args; } -#line 4408 "reflect.h2" +#line 4447 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8194,7 +8280,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} }} } -#line 4459 "reflect.h2" +#line 4498 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8202,7 +8288,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} { auto i{0}; -#line 4465 "reflect.h2" +#line 4504 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8216,7 +8302,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4477 "reflect.h2" +#line 4516 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8239,7 +8325,7 @@ auto i{0}; { auto i{0}; -#line 4498 "reflect.h2" +#line 4537 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8264,7 +8350,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4521 "reflect.h2" +#line 4560 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8347,7 +8433,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4603 "reflect.h2" +#line 4642 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8370,7 +8456,7 @@ auto i{0}; { auto i{1}; -#line 4624 "reflect.h2" +#line 4663 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8380,69 +8466,69 @@ auto i{1}; } } -#line 4632 "reflect.h2" +#line 4671 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4638 "reflect.h2" +#line 4677 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4642 "reflect.h2" +#line 4681 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4646 "reflect.h2" +#line 4685 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4650 "reflect.h2" +#line 4689 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4654 "reflect.h2" +#line 4693 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4658 "reflect.h2" +#line 4697 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4662 "reflect.h2" +#line 4701 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4666 "reflect.h2" +#line 4705 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4670 "reflect.h2" +#line 4709 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4674 "reflect.h2" +#line 4713 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4678 "reflect.h2" +#line 4717 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4682 "reflect.h2" +#line 4721 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8467,7 +8553,7 @@ auto i{1}; fwd_expr = cpp2::move(fwd); } -#line 4706 "reflect.h2" +#line 4745 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8508,7 +8594,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4747 "reflect.h2" +#line 4786 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8525,12 +8611,12 @@ auto i{1}; } } -#line 4763 "reflect.h2" +#line 4802 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4767 "reflect.h2" +#line 4806 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -8547,7 +8633,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 4783 "reflect.h2" +#line 4822 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8556,7 +8642,7 @@ auto i{1}; { auto i{0}; -#line 4790 "reflect.h2" +#line 4829 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8571,7 +8657,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4803 "reflect.h2" +#line 4842 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8592,7 +8678,7 @@ auto i{0}; } } -#line 4823 "reflect.h2" +#line 4862 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8625,26 +8711,26 @@ auto i{0}; }}}} } -#line 4864 "reflect.h2" +#line 4903 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4867 "reflect.h2" +#line 4906 "reflect.h2" } -#line 4869 "reflect.h2" +#line 4908 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4874 "reflect.h2" +#line 4913 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4879 "reflect.h2" +#line 4918 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8673,22 +8759,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 4908 "reflect.h2" +#line 4947 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4913 "reflect.h2" +#line 4952 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4918 "reflect.h2" +#line 4957 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4923 "reflect.h2" +#line 4962 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8696,7 +8782,7 @@ auto i{0}; diff += "}\n"; } -#line 4931 "reflect.h2" +#line 4970 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8713,7 +8799,7 @@ auto i{0}; } } -#line 4948 "reflect.h2" +#line 4987 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8763,7 +8849,7 @@ auto i{0}; }} } -#line 4998 "reflect.h2" +#line 5037 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8775,12 +8861,12 @@ auto i{0}; } } -#line 5009 "reflect.h2" +#line 5048 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5013 "reflect.h2" +#line 5052 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8794,73 +8880,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 5026 "reflect.h2" +#line 5065 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5030 "reflect.h2" +#line 5069 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5034 "reflect.h2" +#line 5073 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5038 "reflect.h2" +#line 5077 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5042 "reflect.h2" +#line 5081 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5046 "reflect.h2" +#line 5085 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5050 "reflect.h2" +#line 5089 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5054 "reflect.h2" +#line 5093 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5058 "reflect.h2" +#line 5097 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5062 "reflect.h2" +#line 5101 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5066 "reflect.h2" +#line 5105 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5070 "reflect.h2" +#line 5109 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5074 "reflect.h2" +#line 5113 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5079 "reflect.h2" +#line 5118 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8869,7 +8955,7 @@ auto i{0}; { auto i{0}; -#line 5086 "reflect.h2" +#line 5125 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8884,7 +8970,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5099 "reflect.h2" +#line 5138 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8897,27 +8983,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5111 "reflect.h2" +#line 5150 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5128 "reflect.h2" +#line 5167 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5131 "reflect.h2" +#line 5170 "reflect.h2" } -#line 5133 "reflect.h2" +#line 5172 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5138 "reflect.h2" +#line 5177 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -8977,10 +9063,10 @@ auto i{0}; return ; } -#line 5198 "reflect.h2" +#line 5237 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5201 "reflect.h2" +#line 5240 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -8991,13 +9077,13 @@ auto i{0}; CPP2_UFCS(leave_function)((*cpp2::impl::assert_not_null(ctx))); - CPP2_UFCS(add_member)(decl, diff); + CPP2_UFCS(add_member)(decl, diff.fwd); diff = ""; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5218 "reflect.h2" +#line 5257 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9015,17 +9101,17 @@ auto i{0}; if (is_type_context) { - diff_ad_type += "public " + cpp2::to_string(diff) + "\n"; + diff_ad_type += "public " + cpp2::to_string(diff.fwd) + "\n"; } else { - CPP2_UFCS(add_member)(decl, diff); + CPP2_UFCS(add_member)(decl, diff.fwd); } diff = ""; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5246 "reflect.h2" +#line 5285 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9044,22 +9130,22 @@ auto i{0}; diff += "" + cpp2::to_string(cpp2::move(ad).diff_ad_type) + ""; diff += "}"; - CPP2_UFCS(add_member)(decl, diff); + CPP2_UFCS(add_member)(decl, diff.fwd); diff = ""; } } -#line 5270 "reflect.h2" +#line 5309 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5275 "reflect.h2" +#line 5314 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5281 "reflect.h2" +#line 5320 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9235,7 +9321,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5366 "reflect.h2" +#line 5405 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9251,11 +9337,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5382 "reflect.h2" +#line 5421 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5386 "reflect.h2" +#line 5425 "reflect.h2" // mod: i // mod: m // mod: s @@ -9263,116 +9349,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5395 "reflect.h2" +#line 5434 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5404 "reflect.h2" +#line 5443 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5406 "reflect.h2" +#line 5445 "reflect.h2" } -#line 5408 "reflect.h2" +#line 5447 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5410 "reflect.h2" +#line 5449 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5416 "reflect.h2" +#line 5455 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5417 "reflect.h2" +#line 5456 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5418 "reflect.h2" +#line 5457 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5433 "reflect.h2" +#line 5472 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5436 "reflect.h2" +#line 5475 "reflect.h2" } -#line 5438 "reflect.h2" +#line 5477 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5442 "reflect.h2" +#line 5481 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5454 "reflect.h2" +#line 5493 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5457 "reflect.h2" +#line 5496 "reflect.h2" } -#line 5459 "reflect.h2" +#line 5498 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5463 "reflect.h2" +#line 5502 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5473 "reflect.h2" +#line 5512 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5475 "reflect.h2" +#line 5514 "reflect.h2" } -#line 5477 "reflect.h2" +#line 5516 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5481 "reflect.h2" +#line 5520 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5493 "reflect.h2" +#line 5532 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5496 "reflect.h2" +#line 5535 "reflect.h2" } -#line 5498 "reflect.h2" +#line 5537 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5504 "reflect.h2" +#line 5543 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5510 "reflect.h2" +#line 5549 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9381,7 +9467,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5518 "reflect.h2" +#line 5557 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9397,7 +9483,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5546 "reflect.h2" +#line 5585 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9405,14 +9491,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5554 "reflect.h2" +#line 5593 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5561 "reflect.h2" +#line 5600 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9424,15 +9510,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5573 "reflect.h2" +#line 5612 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5578 "reflect.h2" +#line 5617 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5582 "reflect.h2" +#line 5621 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9453,7 +9539,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5608 "reflect.h2" +#line 5647 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9462,20 +9548,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5617 "reflect.h2" +#line 5656 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5623 "reflect.h2" +#line 5662 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5630 "reflect.h2" +#line 5669 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9490,16 +9576,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5660 "reflect.h2" +#line 5699 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5664 "reflect.h2" +#line 5703 "reflect.h2" } -#line 5670 "reflect.h2" +#line 5709 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9509,7 +9595,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5680 "reflect.h2" +#line 5719 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9517,17 +9603,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5687 "reflect.h2" +#line 5726 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5691 "reflect.h2" +#line 5730 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5698 "reflect.h2" +#line 5737 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9537,7 +9623,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5707 "reflect.h2" +#line 5746 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9545,24 +9631,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5714 "reflect.h2" +#line 5753 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5722 "reflect.h2" +#line 5761 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5726 "reflect.h2" +#line 5765 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5730 "reflect.h2" +#line 5769 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9574,22 +9660,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5741 "reflect.h2" +#line 5780 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5747 "reflect.h2" +#line 5786 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5751 "reflect.h2" +#line 5790 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5755 "reflect.h2" +#line 5794 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9597,7 +9683,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5762 "reflect.h2" +#line 5801 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9609,10 +9695,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5775 "reflect.h2" +#line 5814 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5778 "reflect.h2" +#line 5817 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9652,7 +9738,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5818 "reflect.h2" +#line 5857 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9664,14 +9750,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5829 "reflect.h2" +#line 5868 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5830 "reflect.h2" +#line 5869 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5831 "reflect.h2" +#line 5870 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5833 "reflect.h2" +#line 5872 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9681,10 +9767,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5842 "reflect.h2" +#line 5881 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5844 "reflect.h2" +#line 5883 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9706,14 +9792,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5865 "reflect.h2" +#line 5904 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5866 "reflect.h2" +#line 5905 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5867 "reflect.h2" +#line 5906 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5869 "reflect.h2" +#line 5908 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9727,7 +9813,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5882 "reflect.h2" +#line 5921 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9749,7 +9835,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5903 "reflect.h2" +#line 5942 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9760,12 +9846,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5913 "reflect.h2" +#line 5952 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5914 "reflect.h2" +#line 5953 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5919 "reflect.h2" +#line 5958 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9820,7 +9906,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 5973 "reflect.h2" +#line 6012 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9860,7 +9946,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6012 "reflect.h2" +#line 6051 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9876,21 +9962,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6029 "reflect.h2" +#line 6068 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6030 "reflect.h2" +#line 6069 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6031 "reflect.h2" +#line 6070 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6033 "reflect.h2" +#line 6072 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6048 "reflect.h2" +#line 6087 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9898,7 +9984,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6055 "reflect.h2" +#line 6094 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9908,22 +9994,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6073 "reflect.h2" +#line 6112 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6078 "reflect.h2" +#line 6117 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6084 "reflect.h2" +#line 6123 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6090 "reflect.h2" +#line 6129 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -9932,7 +10018,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6098 "reflect.h2" +#line 6137 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -9944,7 +10030,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6109 "reflect.h2" +#line 6148 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -9952,7 +10038,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6116 "reflect.h2" +#line 6155 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -9973,7 +10059,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6137 "reflect.h2" +#line 6176 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -9983,7 +10069,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6147 "reflect.h2" +#line 6186 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10006,33 +10092,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6171 "reflect.h2" +#line 6210 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6177 "reflect.h2" +#line 6216 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6181 "reflect.h2" +#line 6220 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6187 "reflect.h2" +#line 6226 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6195 "reflect.h2" +#line 6234 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10041,7 +10127,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6203 "reflect.h2" +#line 6242 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10050,22 +10136,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6213 "reflect.h2" +#line 6252 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6217 "reflect.h2" +#line 6256 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6221 "reflect.h2" +#line 6260 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6225 "reflect.h2" +#line 6264 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10089,18 +10175,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6250 "reflect.h2" +#line 6289 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6265 "reflect.h2" +#line 6304 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6267 "reflect.h2" +#line 6306 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10111,15 +10197,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6282 "reflect.h2" +#line 6321 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6285 "reflect.h2" +#line 6324 "reflect.h2" } -#line 6287 "reflect.h2" +#line 6326 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10137,7 +10223,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6304 "reflect.h2" +#line 6343 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10145,7 +10231,7 @@ generation_function_context::generation_function_context(){} } } -#line 6311 "reflect.h2" +#line 6350 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10159,7 +10245,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6324 "reflect.h2" +#line 6363 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10175,14 +10261,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6345 "reflect.h2" +#line 6384 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6347 "reflect.h2" +#line 6386 "reflect.h2" } -#line 6349 "reflect.h2" +#line 6388 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10191,11 +10277,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6364 "reflect.h2" +#line 6403 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6366 "reflect.h2" +#line 6405 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10203,7 +10289,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6373 "reflect.h2" +#line 6412 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10212,37 +10298,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6381 "reflect.h2" +#line 6420 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6395 "reflect.h2" +#line 6434 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6399 "reflect.h2" +#line 6438 "reflect.h2" } -#line 6401 "reflect.h2" +#line 6440 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6405 "reflect.h2" +#line 6444 "reflect.h2" } -#line 6407 "reflect.h2" +#line 6446 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6411 "reflect.h2" +#line 6450 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10251,14 +10337,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6417 "reflect.h2" +#line 6456 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6422 "reflect.h2" +#line 6461 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10271,7 +10357,7 @@ size_t i{0}; } } -#line 6434 "reflect.h2" +#line 6473 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10293,7 +10379,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6455 "reflect.h2" +#line 6494 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10312,7 +10398,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6473 "reflect.h2" +#line 6512 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10328,14 +10414,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6488 "reflect.h2" +#line 6527 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6494 "reflect.h2" +#line 6533 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10343,19 +10429,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6511 "reflect.h2" +#line 6550 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6512 "reflect.h2" +#line 6551 "reflect.h2" { -#line 6517 "reflect.h2" +#line 6556 "reflect.h2" } -#line 6520 "reflect.h2" +#line 6559 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10481,7 +10567,7 @@ size_t i{0}; ); } -#line 6645 "reflect.h2" +#line 6684 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10491,13 +10577,13 @@ size_t i{0}; ); } -#line 6654 "reflect.h2" +#line 6693 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6659 "reflect.h2" +#line 6698 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10508,12 +10594,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6671 "reflect.h2" +#line 6710 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6676 "reflect.h2" +#line 6715 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10547,7 +10633,7 @@ size_t i{0}; } -#line 6712 "reflect.h2" +#line 6751 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10556,19 +10642,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6735 "reflect.h2" +#line 6774 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6736 "reflect.h2" +#line 6775 "reflect.h2" { -#line 6741 "reflect.h2" +#line 6780 "reflect.h2" } -#line 6743 "reflect.h2" +#line 6782 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10670,19 +10756,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6844 "reflect.h2" +#line 6883 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6848 "reflect.h2" +#line 6887 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6872 "reflect.h2" +#line 6911 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10701,7 +10787,7 @@ size_t i{0}; return r; } -#line 6890 "reflect.h2" +#line 6929 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10716,7 +10802,7 @@ size_t i{0}; return r; } -#line 6904 "reflect.h2" +#line 6943 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10876,7 +10962,7 @@ size_t i{0}; } } -#line 7063 "reflect.h2" +#line 7102 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10885,7 +10971,7 @@ size_t i{0}; return r; } -#line 7071 "reflect.h2" +#line 7110 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10904,7 +10990,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7089 "reflect.h2" +#line 7128 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -10936,7 +11022,7 @@ size_t i{0}; } } -#line 7120 "reflect.h2" +#line 7159 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -10947,7 +11033,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7132 "reflect.h2" +#line 7171 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -10986,7 +11072,7 @@ size_t i{0}; return r; } -#line 7173 "reflect.h2" +#line 7212 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11004,7 +11090,7 @@ size_t i{0}; }} } -#line 7193 "reflect.h2" +#line 7232 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11018,16 +11104,16 @@ size_t i{0}; } } -#line 7219 "reflect.h2" +#line 7258 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7222 "reflect.h2" +#line 7261 "reflect.h2" } -#line 7224 "reflect.h2" +#line 7263 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11039,7 +11125,7 @@ size_t i{0}; } } -#line 7235 "reflect.h2" +#line 7274 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11047,14 +11133,14 @@ size_t i{0}; return r; } -#line 7242 "reflect.h2" +#line 7281 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7250 "reflect.h2" +#line 7289 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11080,7 +11166,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7278 "reflect.h2" +#line 7317 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11106,11 +11192,11 @@ size_t i{0}; return r; } -#line 7315 "reflect.h2" +#line 7354 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7317 "reflect.h2" +#line 7356 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11184,7 +11270,7 @@ size_t i{0}; return nullptr; } -#line 7390 "reflect.h2" +#line 7429 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11197,7 +11283,7 @@ size_t i{0}; }} } -#line 7402 "reflect.h2" +#line 7441 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11211,7 +11297,7 @@ size_t i{0}; }} } -#line 7415 "reflect.h2" +#line 7454 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11231,7 +11317,7 @@ size_t i{0}; return r; } -#line 7434 "reflect.h2" +#line 7473 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11242,7 +11328,7 @@ size_t i{0}; return r; } -#line 7444 "reflect.h2" +#line 7483 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11254,14 +11340,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7455 "reflect.h2" +#line 7494 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7467 "reflect.h2" +#line 7506 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11285,7 +11371,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7491 "reflect.h2" +#line 7530 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11295,7 +11381,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7503 "reflect.h2" +#line 7542 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11311,7 +11397,7 @@ size_t i{0}; } } -#line 7523 "reflect.h2" +#line 7562 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11329,15 +11415,15 @@ size_t i{0}; }} } -#line 7559 "reflect.h2" +#line 7598 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7562 "reflect.h2" +#line 7601 "reflect.h2" } -#line 7564 "reflect.h2" +#line 7603 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11373,7 +11459,7 @@ size_t i{0}; return source; } -#line 7599 "reflect.h2" +#line 7638 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11389,7 +11475,7 @@ size_t i{0}; } } -#line 7615 "reflect.h2" +#line 7654 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11398,7 +11484,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11453,7 +11539,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7684 "reflect.h2" +#line 7723 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11575,7 +11661,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7806 "reflect.h2" +#line 7845 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 5b4c022fb..d9bab81a6 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4332,17 +4332,56 @@ autodiff_context: type = { } } +autodiff_diff_code: type = { + public ctx: *autodiff_context; + + public fwd: std::string = ""; + public rws: std::string = ""; + + operator=:(out this, ctx_: *autodiff_context) = { + ctx = ctx_; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. + operator=:(inout this, v: std::string) = { + ctx = ctx; + fwd = v; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. + operator+=: (inout this, v: std::string) = { + fwd += v; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. + operator+=: (inout this, v: autodiff_diff_code) = { + fwd += v.fwd; + } + + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. + empty: (this) -> bool = { + return fwd.empty(); + } +} + +// // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. +// to_string: (v: autodiff_diff_code) -> std::string = { +// return v.fwd; +// } + autodiff_handler_base: type = { public ctx: *autodiff_context; - public diff : std::string = ""; + public diff : autodiff_diff_code; operator=: (out this, ctx_: *autodiff_context) = { ctx = ctx_; + diff = (ctx); } + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. append: (inout this, in_ref o: autodiff_handler_base) = { - diff += o.diff; + diff += o.diff.fwd; } } @@ -5208,7 +5247,7 @@ autodiff_declaration_handler: type = { ctx*.leave_function(); - decl.add_member( diff ); + decl.add_member( diff.fwd ); diff = ""; ctx*.add_as_differentiated(f); @@ -5232,10 +5271,10 @@ autodiff_declaration_handler: type = { if is_type_context { - diff_ad_type += "public (diff)$\n"; + diff_ad_type += "public (diff.fwd)$\n"; } else { - decl.add_member(diff); + decl.add_member(diff.fwd); } diff = ""; @@ -5261,7 +5300,7 @@ autodiff_declaration_handler: type = { diff += "(ad.diff_ad_type)$"; diff += "}"; - decl.add_member(diff); + decl.add_member(diff.fwd); diff = ""; } } From e48a43f0ccc924ae04dedba66effe79351f7f5e9 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Sat, 23 Aug 2025 10:27:14 +0200 Subject: [PATCH 40/54] Reverse handling of function declaration. --- include/cpp2taylor.h | 187 ++-- include/cpp2taylor.h2 | 1 + regression-tests/pure2-autodiff.cpp2 | 19 + source/reflect.h | 1369 ++++++++++++++------------ source/reflect.h2 | 160 ++- 5 files changed, 1012 insertions(+), 724 deletions(-) diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index 5ba6f124f..1b85a3d1f 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -16,7 +16,7 @@ namespace cpp2 { template class taylor; -#line 242 "cpp2taylor.h2" +#line 243 "cpp2taylor.h2" } @@ -37,84 +37,84 @@ template class taylor { #line 10 "cpp2taylor.h2" public: auto operator=(R const& d1) -> taylor& ; -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" public: taylor(taylor const& that); -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" public: auto operator=(taylor const& that) -> taylor& ; -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" public: taylor(taylor&& that) noexcept; -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" public: auto operator=(taylor&& that) noexcept -> taylor& ; public: taylor(std::initializer_list const& l); -#line 15 "cpp2taylor.h2" +#line 16 "cpp2taylor.h2" public: auto operator=(std::initializer_list const& l) -> taylor& ; -#line 22 "cpp2taylor.h2" +#line 23 "cpp2taylor.h2" // C++ interface public: [[nodiscard]] auto operator[](cpp2::impl::in k) const& -> R; -#line 34 "cpp2taylor.h2" +#line 35 "cpp2taylor.h2" public: auto set(cpp2::impl::in k, cpp2::impl::in value) & -> void; -#line 44 "cpp2taylor.h2" +#line 45 "cpp2taylor.h2" // C++2 interface / AD interface public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; -#line 56 "cpp2taylor.h2" +#line 57 "cpp2taylor.h2" // Overload for simple handling of connected adds. public: [[nodiscard]] auto operator+(cpp2::impl::in o) const& -> taylor; -#line 61 "cpp2taylor.h2" +#line 62 "cpp2taylor.h2" // Overload for simple handling of connected minuses. public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; -#line 66 "cpp2taylor.h2" +#line 67 "cpp2taylor.h2" // Overload for simple handling of prefix +. public: [[nodiscard]] auto operator+() const& -> taylor; -#line 71 "cpp2taylor.h2" +#line 72 "cpp2taylor.h2" // Overload for simple handling of prefix -. public: [[nodiscard]] auto operator-() const& -> taylor; -#line 83 "cpp2taylor.h2" +#line 84 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 94 "cpp2taylor.h2" +#line 95 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 105 "cpp2taylor.h2" +#line 106 "cpp2taylor.h2" public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 118 "cpp2taylor.h2" +#line 119 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 136 "cpp2taylor.h2" +#line 137 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; -#line 155 "cpp2taylor.h2" +#line 156 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; -#line 174 "cpp2taylor.h2" +#line 175 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; -#line 193 "cpp2taylor.h2" +#line 194 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; -#line 210 "cpp2taylor.h2" +#line 211 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; -#line 220 "cpp2taylor.h2" +#line 221 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; -#line 229 "cpp2taylor.h2" +#line 230 "cpp2taylor.h2" }; template [[nodiscard]] auto to_string(taylor const& o) -> std::string; -#line 242 "cpp2taylor.h2" +#line 243 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H @@ -131,91 +131,94 @@ namespace cpp2 { template taylor::taylor(){} #line 10 "cpp2taylor.h2" template taylor::taylor(R const& d1) - : v{ d1 }{ + : v{ }{ #line 12 "cpp2taylor.h2" + CPP2_ASSERT_IN_BOUNDS_LITERAL(v, 0) = d1; } #line 10 "cpp2taylor.h2" template auto taylor::operator=(R const& d1) -> taylor& { - v = d1; - return *this; + v = {}; #line 12 "cpp2taylor.h2" - } + CPP2_ASSERT_IN_BOUNDS_LITERAL(v, 0) = d1; + return *this; #line 13 "cpp2taylor.h2" + } +#line 14 "cpp2taylor.h2" template taylor::taylor(taylor const& that) : v{ that.v }{} -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" template auto taylor::operator=(taylor const& that) -> taylor& { v = that.v; return *this; } -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" template taylor::taylor(taylor&& that) noexcept : v{ std::move(that).v }{} -#line 13 "cpp2taylor.h2" +#line 14 "cpp2taylor.h2" template auto taylor::operator=(taylor&& that) noexcept -> taylor& { v = std::move(that).v; return *this; } -#line 15 "cpp2taylor.h2" +#line 16 "cpp2taylor.h2" template taylor::taylor(std::initializer_list const& l){ { auto i{1}; -#line 17 "cpp2taylor.h2" +#line 18 "cpp2taylor.h2" for ( auto const& cur : l ) { set(i, cur); } } -#line 20 "cpp2taylor.h2" +#line 21 "cpp2taylor.h2" } -#line 15 "cpp2taylor.h2" +#line 16 "cpp2taylor.h2" template auto taylor::operator=(std::initializer_list const& l) -> taylor& { v = {}; { auto i{1}; -#line 17 "cpp2taylor.h2" +#line 18 "cpp2taylor.h2" for ( auto const& cur : l ) { set(i, cur); } } return *this; -#line 20 "cpp2taylor.h2" +#line 21 "cpp2taylor.h2" } -#line 24 "cpp2taylor.h2" +#line 25 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator[](cpp2::impl::in k) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } R r {CPP2_ASSERT_IN_BOUNDS(v, k - 1)}; { auto i{2}; -#line 28 "cpp2taylor.h2" +#line 29 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { r *= i; } } -#line 31 "cpp2taylor.h2" +#line 32 "cpp2taylor.h2" return r; } -#line 34 "cpp2taylor.h2" +#line 35 "cpp2taylor.h2" template auto taylor::set(cpp2::impl::in k, cpp2::impl::in value) & -> void{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } CPP2_ASSERT_IN_BOUNDS(v, k - 1) = value; { auto i{2}; -#line 39 "cpp2taylor.h2" +#line 40 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(v, k - 1)),i); } } -#line 42 "cpp2taylor.h2" +#line 43 "cpp2taylor.h2" } -#line 46 "cpp2taylor.h2" +#line 47 "cpp2taylor.h2" template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 0, _1 = i, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } @@ -226,93 +229,93 @@ auto i{2}; return CPP2_ASSERT_IN_BOUNDS(v, i - 1); } -#line 57 "cpp2taylor.h2" +#line 58 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+(cpp2::impl::in o) const& -> taylor{ return add(o, 0.0, 0.0); // Primal values are not required. } -#line 62 "cpp2taylor.h2" +#line 63 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-(cpp2::impl::in o) const& -> taylor{ return sub(o, 0.0, 0.0); // Primal values are not required. } -#line 67 "cpp2taylor.h2" +#line 68 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+() const& -> taylor{ return (*this); } -#line 72 "cpp2taylor.h2" +#line 73 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-() const& -> taylor{ taylor r {}; { auto k{1}; -#line 76 "cpp2taylor.h2" +#line 77 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = -CPP2_ASSERT_IN_BOUNDS(v, k - 1); } } -#line 80 "cpp2taylor.h2" +#line 81 "cpp2taylor.h2" return r; } -#line 83 "cpp2taylor.h2" +#line 84 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 87 "cpp2taylor.h2" +#line 88 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } -#line 91 "cpp2taylor.h2" +#line 92 "cpp2taylor.h2" return r; } -#line 94 "cpp2taylor.h2" +#line 95 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 98 "cpp2taylor.h2" +#line 99 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } -#line 102 "cpp2taylor.h2" +#line 103 "cpp2taylor.h2" return r; } -#line 105 "cpp2taylor.h2" +#line 106 "cpp2taylor.h2" template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 109 "cpp2taylor.h2" +#line 110 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{0}; -#line 111 "cpp2taylor.h2" +#line 112 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } -#line 114 "cpp2taylor.h2" +#line 115 "cpp2taylor.h2" } } -#line 115 "cpp2taylor.h2" +#line 116 "cpp2taylor.h2" return r; } -#line 118 "cpp2taylor.h2" +#line 119 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; @@ -321,26 +324,26 @@ auto j{0}; { auto k{1}; -#line 125 "cpp2taylor.h2" +#line 126 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; -#line 128 "cpp2taylor.h2" +#line 129 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } -#line 131 "cpp2taylor.h2" +#line 132 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 133 "cpp2taylor.h2" +#line 134 "cpp2taylor.h2" return r; } -#line 136 "cpp2taylor.h2" +#line 137 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; @@ -349,27 +352,27 @@ auto j{0}; { auto k{1}; -#line 143 "cpp2taylor.h2" +#line 144 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; -#line 146 "cpp2taylor.h2" +#line 147 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } -#line 149 "cpp2taylor.h2" +#line 150 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 152 "cpp2taylor.h2" +#line 153 "cpp2taylor.h2" return r; } -#line 155 "cpp2taylor.h2" +#line 156 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; @@ -378,27 +381,27 @@ auto j{1}; { auto k{1}; -#line 162 "cpp2taylor.h2" +#line 163 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; -#line 165 "cpp2taylor.h2" +#line 166 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } -#line 168 "cpp2taylor.h2" +#line 169 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } -#line 171 "cpp2taylor.h2" +#line 172 "cpp2taylor.h2" return r; } -#line 174 "cpp2taylor.h2" +#line 175 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; @@ -407,52 +410,52 @@ auto j{1}; { auto k{1}; -#line 181 "cpp2taylor.h2" +#line 182 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 183 "cpp2taylor.h2" +#line 184 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } -#line 186 "cpp2taylor.h2" +#line 187 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } -#line 189 "cpp2taylor.h2" +#line 190 "cpp2taylor.h2" return r; } -#line 193 "cpp2taylor.h2" +#line 194 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; -#line 198 "cpp2taylor.h2" +#line 199 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 200 "cpp2taylor.h2" +#line 201 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); } } -#line 204 "cpp2taylor.h2" +#line 205 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } -#line 207 "cpp2taylor.h2" +#line 208 "cpp2taylor.h2" } -#line 210 "cpp2taylor.h2" +#line 211 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -463,7 +466,7 @@ auto j{1}; return r; } -#line 220 "cpp2taylor.h2" +#line 221 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -474,18 +477,18 @@ auto j{1}; return r; } -#line 231 "cpp2taylor.h2" +#line 232 "cpp2taylor.h2" template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ std::string r {"("}; { auto i{1}; -#line 234 "cpp2taylor.h2" +#line 235 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; } } -#line 237 "cpp2taylor.h2" +#line 238 "cpp2taylor.h2" r += " )"; return r; diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index 845af5d0f..879689e60 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -8,6 +8,7 @@ taylor: type = { operator=:(out this) = {} operator=:(out this, d1: R) = { + v = (); v[0] = d1; } operator=:(out this, that) = {} diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 3dd253dde..f7d46181f 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -190,6 +190,13 @@ ad_test: @autodiff @print type = { r = t.add(y); } } + +ad_test_reverse: @autodiff<"reverse"> @print type = { + + add_1: (x: double, y: double) -> (r: double) = { + r = x + y; + } +} } ad_test_twice: @autodiff @autodiff<"suffix=_d2"> @print type = { @@ -202,6 +209,12 @@ write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$) = (r = (ret.r)$, r_d = (ret.r_d)$)" << std::endl; } +write_output_reverse: (func: std::string, x: double, inout x_b: double, y: double, inout y_b: double, in r_b: double, ret) = { + std::cout << "diff((func)$) at (x = (x)$, y = (y)$, r_b = (r_b)$) = (r = (ret)$, x_b = (x_b)$, y_b = (y_b)$)" << std::endl; + x_b = 0.0; + y_b = 0.0; +} + main: () = { x: double = 2.0; @@ -240,6 +253,12 @@ main: () = { write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, y, y_d)); + x_b: double = 0.0; + y_b: double = 0.0; + w_b: double = 1.0; + + write_output_reverse("x + y", x, y, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); + r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; } diff --git a/source/reflect.h b/source/reflect.h index aa6fb3d35..aae474c41 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -121,95 +121,95 @@ class autodiff_declaration_stack_item; class autodiff_context; -#line 4335 "reflect.h2" +#line 4383 "reflect.h2" class autodiff_diff_code; -#line 4372 "reflect.h2" +#line 4428 "reflect.h2" class autodiff_handler_base; -#line 4388 "reflect.h2" +#line 4444 "reflect.h2" class autodiff_expression_handler; -#line 4895 "reflect.h2" +#line 4951 "reflect.h2" class autodiff_stmt_handler; -#line 5156 "reflect.h2" +#line 5212 "reflect.h2" class autodiff_declaration_handler; -#line 5423 "reflect.h2" +#line 5545 "reflect.h2" class expression_flags; -#line 5439 "reflect.h2" +#line 5561 "reflect.h2" class regex_token; -#line 5466 "reflect.h2" +#line 5588 "reflect.h2" class regex_token_check; -#line 5487 "reflect.h2" +#line 5609 "reflect.h2" class regex_token_code; -#line 5508 "reflect.h2" +#line 5630 "reflect.h2" class regex_token_empty; -#line 5526 "reflect.h2" +#line 5648 "reflect.h2" class regex_token_list; -#line 5578 "reflect.h2" +#line 5700 "reflect.h2" class parse_context_group_state; -#line 5639 "reflect.h2" +#line 5761 "reflect.h2" class parse_context_branch_reset_state; -#line 5682 "reflect.h2" +#line 5804 "reflect.h2" class parse_context; -#line 6083 "reflect.h2" +#line 6205 "reflect.h2" class generation_function_context; -#line 6101 "reflect.h2" +#line 6223 "reflect.h2" class generation_context; -#line 6300 "reflect.h2" +#line 6422 "reflect.h2" class alternative_token; -#line 6315 "reflect.h2" +#line 6437 "reflect.h2" class alternative_token_gen; -#line 6380 "reflect.h2" +#line 6502 "reflect.h2" class any_token; -#line 6397 "reflect.h2" +#line 6519 "reflect.h2" class atomic_group_token; -#line 6427 "reflect.h2" +#line 6549 "reflect.h2" class char_token; -#line 6542 "reflect.h2" +#line 6664 "reflect.h2" class class_token; -#line 6766 "reflect.h2" +#line 6888 "reflect.h2" class group_ref_token; -#line 6903 "reflect.h2" +#line 7025 "reflect.h2" class group_token; -#line 7250 "reflect.h2" +#line 7372 "reflect.h2" class lookahead_lookbehind_token; -#line 7345 "reflect.h2" +#line 7467 "reflect.h2" class range_token; -#line 7502 "reflect.h2" +#line 7624 "reflect.h2" class special_range_token; -#line 7588 "reflect.h2" +#line 7710 "reflect.h2" template class regex_generator; -#line 7845 "reflect.h2" +#line 7967 "reflect.h2" } } @@ -1780,70 +1780,78 @@ class autodiff_context { public: auto create_namespace_stack(cpp2::impl::in t) & -> void; #line 4136 "reflect.h2" + public: [[nodiscard]] auto is_forward() const& -> decltype(auto); + public: [[nodiscard]] auto is_reverse() const& -> decltype(auto); public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4143 "reflect.h2" +#line 4145 "reflect.h2" public: [[nodiscard]] auto get_fwd_ad_type(cpp2::impl::in type) & -> std::string; + +#line 4163 "reflect.h2" + public: [[nodiscard]] auto get_rws_ad_type(cpp2::impl::in type) & -> std::string; + +#line 4181 "reflect.h2" + public: [[nodiscard]] auto get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style; using lookup_declaration_ret = std::vector; -#line 4161 "reflect.h2" +#line 4209 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; -#line 4184 "reflect.h2" +#line 4232 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4201 "reflect.h2" +#line 4249 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; using lookup_member_function_declaration_ret = std::vector; -#line 4211 "reflect.h2" +#line 4259 "reflect.h2" public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4221 "reflect.h2" +#line 4269 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4231 "reflect.h2" +#line 4279 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4253 "reflect.h2" +#line 4301 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4261 "reflect.h2" +#line 4309 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4281 "reflect.h2" +#line 4329 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4291 "reflect.h2" +#line 4339 "reflect.h2" public: auto enter_function() & -> void; -#line 4296 "reflect.h2" +#line 4344 "reflect.h2" public: auto leave_function() & -> void; -#line 4300 "reflect.h2" +#line 4348 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4313 "reflect.h2" +#line 4361 "reflect.h2" public: auto pop_stack() & -> void; -#line 4328 "reflect.h2" +#line 4376 "reflect.h2" public: auto finish() & -> void; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4333 "reflect.h2" +#line 4381 "reflect.h2" }; class autodiff_diff_code { @@ -1853,49 +1861,55 @@ class autodiff_diff_code { public: std::string rws {""}; public: autodiff_diff_code(autodiff_context* ctx_); -#line 4341 "reflect.h2" +#line 4389 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_diff_code& ; -#line 4346 "reflect.h2" +#line 4393 "reflect.h2" + public: auto add_forward(cpp2::impl::in v) & -> void; + public: auto add_reverse(cpp2::impl::in v) & -> void; + + public: auto reset() & -> void; + +#line 4402 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4352 "reflect.h2" +#line 4408 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4357 "reflect.h2" +#line 4413 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4362 "reflect.h2" +#line 4418 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_diff_code const&) -> void = delete; -#line 4365 "reflect.h2" +#line 4421 "reflect.h2" }; -#line 4372 "reflect.h2" +#line 4428 "reflect.h2" class autodiff_handler_base { public: autodiff_context* ctx; public: autodiff_diff_code diff; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4377 "reflect.h2" +#line 4433 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4383 "reflect.h2" +#line 4439 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4386 "reflect.h2" +#line 4442 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4392 "reflect.h2" +#line 4448 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1903,28 +1917,28 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4401 "reflect.h2" +#line 4457 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; -#line 4410 "reflect.h2" +#line 4466 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; -#line 4414 "reflect.h2" +#line 4470 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4420 "reflect.h2" +#line 4476 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; -#line 4424 "reflect.h2" +#line 4480 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4433 "reflect.h2" +#line 4489 "reflect.h2" public: class primal_fwd_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -1932,176 +1946,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_name(); -#line 4436 "reflect.h2" +#line 4492 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4447 "reflect.h2" +#line 4503 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_name; -#line 4498 "reflect.h2" +#line 4554 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4642 "reflect.h2" +#line 4698 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4677 "reflect.h2" +#line 4733 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4681 "reflect.h2" +#line 4737 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4685 "reflect.h2" +#line 4741 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4689 "reflect.h2" +#line 4745 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4693 "reflect.h2" +#line 4749 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4697 "reflect.h2" +#line 4753 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4701 "reflect.h2" +#line 4757 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4705 "reflect.h2" +#line 4761 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4709 "reflect.h2" +#line 4765 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4713 "reflect.h2" +#line 4769 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4717 "reflect.h2" +#line 4773 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4721 "reflect.h2" +#line 4777 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4745 "reflect.h2" +#line 4801 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4802 "reflect.h2" +#line 4858 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4806 "reflect.h2" +#line 4862 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4822 "reflect.h2" +#line 4878 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4862 "reflect.h2" +#line 4918 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4893 "reflect.h2" +#line 4949 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4899 "reflect.h2" +#line 4955 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4908 "reflect.h2" +#line 4964 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4913 "reflect.h2" +#line 4969 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4918 "reflect.h2" +#line 4974 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4947 "reflect.h2" +#line 5003 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4952 "reflect.h2" +#line 5008 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4957 "reflect.h2" +#line 5013 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4962 "reflect.h2" +#line 5018 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4970 "reflect.h2" +#line 5026 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 4987 "reflect.h2" +#line 5043 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5037 "reflect.h2" +#line 5093 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5048 "reflect.h2" +#line 5104 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5052 "reflect.h2" +#line 5108 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5065 "reflect.h2" +#line 5121 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5069 "reflect.h2" +#line 5125 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5073 "reflect.h2" +#line 5129 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5077 "reflect.h2" +#line 5133 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5081 "reflect.h2" +#line 5137 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5085 "reflect.h2" +#line 5141 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5089 "reflect.h2" +#line 5145 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5093 "reflect.h2" +#line 5149 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5097 "reflect.h2" +#line 5153 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5101 "reflect.h2" +#line 5157 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5105 "reflect.h2" +#line 5161 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5109 "reflect.h2" +#line 5165 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5113 "reflect.h2" +#line 5169 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5118 "reflect.h2" +#line 5174 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5150 "reflect.h2" +#line 5206 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5154 "reflect.h2" +#line 5210 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5160 "reflect.h2" +#line 5216 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2111,37 +2125,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 5172 "reflect.h2" +#line 5228 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5177 "reflect.h2" +#line 5233 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5257 "reflect.h2" +#line 5379 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5285 "reflect.h2" +#line 5407 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5309 "reflect.h2" +#line 5431 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5314 "reflect.h2" +#line 5436 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5317 "reflect.h2" +#line 5439 "reflect.h2" }; -#line 5320 "reflect.h2" +#line 5442 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5419 "reflect.h2" +#line 5541 "reflect.h2" using error_func = std::function x)>; -#line 5423 "reflect.h2" +#line 5545 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2176,20 +2190,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5431 "reflect.h2" +#line 5553 "reflect.h2" }; -#line 5439 "reflect.h2" +#line 5561 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5447 "reflect.h2" +#line 5569 "reflect.h2" public: explicit regex_token(); -#line 5452 "reflect.h2" +#line 5574 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2201,103 +2215,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5458 "reflect.h2" +#line 5580 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5464 "reflect.h2" +#line 5586 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5470 "reflect.h2" +#line 5592 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5477 "reflect.h2" +#line 5599 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5481 "reflect.h2" +#line 5603 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5482 "reflect.h2" +#line 5604 "reflect.h2" }; -#line 5485 "reflect.h2" +#line 5607 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5491 "reflect.h2" +#line 5613 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5498 "reflect.h2" +#line 5620 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5502 "reflect.h2" +#line 5624 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5503 "reflect.h2" +#line 5625 "reflect.h2" }; -#line 5506 "reflect.h2" +#line 5628 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5512 "reflect.h2" +#line 5634 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5516 "reflect.h2" +#line 5638 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5520 "reflect.h2" +#line 5642 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5521 "reflect.h2" +#line 5643 "reflect.h2" }; -#line 5524 "reflect.h2" +#line 5646 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5530 "reflect.h2" +#line 5652 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5537 "reflect.h2" +#line 5659 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5543 "reflect.h2" +#line 5665 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5549 "reflect.h2" +#line 5671 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5557 "reflect.h2" +#line 5679 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2305,10 +2319,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5569 "reflect.h2" +#line 5691 "reflect.h2" }; -#line 5572 "reflect.h2" +#line 5694 "reflect.h2" // // Parse and generation context. // @@ -2324,33 +2338,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5592 "reflect.h2" +#line 5714 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5599 "reflect.h2" +#line 5721 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5611 "reflect.h2" +#line 5733 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5616 "reflect.h2" +#line 5738 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5620 "reflect.h2" +#line 5742 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5634 "reflect.h2" +#line 5756 "reflect.h2" }; -#line 5637 "reflect.h2" +#line 5759 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2363,25 +2377,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5655 "reflect.h2" +#line 5777 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5661 "reflect.h2" +#line 5783 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5668 "reflect.h2" +#line 5790 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5675 "reflect.h2" +#line 5797 "reflect.h2" }; -#line 5678 "reflect.h2" +#line 5800 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2397,7 +2411,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5694 "reflect.h2" +#line 5816 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2405,64 +2419,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5705 "reflect.h2" +#line 5827 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5718 "reflect.h2" +#line 5840 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5726 "reflect.h2" +#line 5848 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5730 "reflect.h2" +#line 5852 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5734 "reflect.h2" +#line 5856 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5746 "reflect.h2" +#line 5868 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5753 "reflect.h2" +#line 5875 "reflect.h2" public: auto next_alternative() & -> void; -#line 5759 "reflect.h2" +#line 5881 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5765 "reflect.h2" +#line 5887 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5769 "reflect.h2" +#line 5891 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5780 "reflect.h2" +#line 5902 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5784 "reflect.h2" +#line 5906 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5790 "reflect.h2" +#line 5912 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5794 "reflect.h2" +#line 5916 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5801 "reflect.h2" +#line 5923 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5812 "reflect.h2" +#line 5934 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2470,51 +2484,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5856 "reflect.h2" +#line 5978 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5868 "reflect.h2" +#line 5990 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 5881 "reflect.h2" +#line 6003 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 5904 "reflect.h2" +#line 6026 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 5921 "reflect.h2" +#line 6043 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 5942 "reflect.h2" +#line 6064 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 5952 "reflect.h2" +#line 6074 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 5956 "reflect.h2" +#line 6078 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6012 "reflect.h2" +#line 6134 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6051 "reflect.h2" +#line 6173 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6066 "reflect.h2" +#line 6188 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2526,10 +2540,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6077 "reflect.h2" +#line 6199 "reflect.h2" }; -#line 6080 "reflect.h2" +#line 6202 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2539,16 +2553,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6094 "reflect.h2" +#line 6216 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6097 "reflect.h2" +#line 6219 "reflect.h2" }; -#line 6100 "reflect.h2" +#line 6222 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2568,68 +2582,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6122 "reflect.h2" +#line 6244 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6128 "reflect.h2" +#line 6250 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6137 "reflect.h2" +#line 6259 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6148 "reflect.h2" +#line 6270 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6155 "reflect.h2" +#line 6277 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6175 "reflect.h2" +#line 6297 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6185 "reflect.h2" +#line 6307 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6208 "reflect.h2" +#line 6330 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6216 "reflect.h2" +#line 6338 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6220 "reflect.h2" +#line 6342 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6226 "reflect.h2" +#line 6348 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6232 "reflect.h2" +#line 6354 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6242 "reflect.h2" +#line 6364 "reflect.h2" public: auto finish_context() & -> void; -#line 6250 "reflect.h2" +#line 6372 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6256 "reflect.h2" +#line 6378 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6260 "reflect.h2" +#line 6382 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6264 "reflect.h2" +#line 6386 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6288 "reflect.h2" +#line 6410 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2637,7 +2651,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6294 "reflect.h2" +#line 6416 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2657,27 +2671,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6313 "reflect.h2" +#line 6435 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6319 "reflect.h2" +#line 6441 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6326 "reflect.h2" +#line 6448 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6343 "reflect.h2" +#line 6465 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6350 "reflect.h2" +#line 6472 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6363 "reflect.h2" +#line 6485 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2685,19 +2699,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6375 "reflect.h2" +#line 6497 "reflect.h2" }; -#line 6378 "reflect.h2" +#line 6500 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6384 "reflect.h2" +#line 6506 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6388 "reflect.h2" +#line 6510 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2705,7 +2719,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6393 "reflect.h2" +#line 6515 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2713,17 +2727,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6401 "reflect.h2" +#line 6523 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6412 "reflect.h2" +#line 6534 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6420 "reflect.h2" +#line 6542 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2731,7 +2745,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6423 "reflect.h2" +#line 6545 "reflect.h2" }; // Regex syntax: a @@ -2739,34 +2753,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6431 "reflect.h2" +#line 6553 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6440 "reflect.h2" +#line 6562 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6446 "reflect.h2" +#line 6568 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6450 "reflect.h2" +#line 6572 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6473 "reflect.h2" +#line 6595 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6494 "reflect.h2" +#line 6616 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6512 "reflect.h2" +#line 6634 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6527 "reflect.h2" +#line 6649 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6533 "reflect.h2" +#line 6655 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2774,33 +2788,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6537 "reflect.h2" +#line 6659 "reflect.h2" }; -#line 6540 "reflect.h2" +#line 6662 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6546 "reflect.h2" +#line 6668 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6558 "reflect.h2" +#line 6680 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6684 "reflect.h2" +#line 6806 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6693 "reflect.h2" +#line 6815 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6698 "reflect.h2" +#line 6820 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2808,20 +2822,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6705 "reflect.h2" +#line 6827 "reflect.h2" }; -#line 6708 "reflect.h2" +#line 6830 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6749 "reflect.h2" +#line 6871 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6760 "reflect.h2" +#line 6882 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2831,20 +2845,20 @@ class class_token class group_ref_token : public regex_token { -#line 6770 "reflect.h2" +#line 6892 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6782 "reflect.h2" +#line 6904 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6883 "reflect.h2" +#line 7005 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6887 "reflect.h2" +#line 7009 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2852,10 +2866,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 6890 "reflect.h2" +#line 7012 "reflect.h2" }; -#line 6893 "reflect.h2" +#line 7015 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2869,29 +2883,29 @@ class group_ref_token class group_token : public regex_token { -#line 6907 "reflect.h2" +#line 7029 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 6929 "reflect.h2" +#line 7051 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 6943 "reflect.h2" +#line 7065 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7102 "reflect.h2" +#line 7224 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7110 "reflect.h2" +#line 7232 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7128 "reflect.h2" +#line 7250 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7159 "reflect.h2" +#line 7281 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2900,25 +2914,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7166 "reflect.h2" +#line 7288 "reflect.h2" }; -#line 7169 "reflect.h2" +#line 7291 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7210 "reflect.h2" +#line 7332 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7230 "reflect.h2" +#line 7352 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7246 "reflect.h2" +#line 7368 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2926,20 +2940,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7254 "reflect.h2" +#line 7376 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7263 "reflect.h2" +#line 7385 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7274 "reflect.h2" +#line 7396 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7281 "reflect.h2" +#line 7403 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2947,26 +2961,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7284 "reflect.h2" +#line 7406 "reflect.h2" }; -#line 7287 "reflect.h2" +#line 7409 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7315 "reflect.h2" +#line 7437 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7343 "reflect.h2" +#line 7465 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7349 "reflect.h2" +#line 7471 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2976,22 +2990,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7429 "reflect.h2" +#line 7551 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7441 "reflect.h2" +#line 7563 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7454 "reflect.h2" +#line 7576 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7473 "reflect.h2" +#line 7595 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7483 "reflect.h2" +#line 7605 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7494 "reflect.h2" +#line 7616 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -2999,16 +3013,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7497 "reflect.h2" +#line 7619 "reflect.h2" }; -#line 7500 "reflect.h2" +#line 7622 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7506 "reflect.h2" +#line 7628 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3017,7 +3031,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7536 "reflect.h2" +#line 7658 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3026,14 +3040,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7558 "reflect.h2" +#line 7680 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7580 "reflect.h2" +#line 7702 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3054,24 +3068,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7603 "reflect.h2" +#line 7725 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7638 "reflect.h2" +#line 7760 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7652 "reflect.h2" +#line 7774 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7664 "reflect.h2" +#line 7786 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7719 "reflect.h2" +#line 7841 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3082,7 +3096,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7845 "reflect.h2" +#line 7967 "reflect.h2" } } @@ -7868,15 +7882,19 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } #line 4136 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_forward() const& -> decltype(auto) { return !(reverse) || (reverse && order != 1); } +#line 4137 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_reverse() const& -> decltype(auto) { return reverse; } +#line 4138 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4138 "reflect.h2" +#line 4140 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4143 "reflect.h2" +#line 4145 "reflect.h2" [[nodiscard]] auto autodiff_context::get_fwd_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -7895,10 +7913,58 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", fwd_ad_type); } -#line 4161 "reflect.h2" +#line 4163 "reflect.h2" + [[nodiscard]] auto autodiff_context::get_rws_ad_type(cpp2::impl::in type) & -> std::string{ + auto type_d {type}; + + if ("double" != type) { + auto type_decls {lookup_type_declaration(type)}; + if (!(CPP2_UFCS(empty)(type_decls))) { + // We found a cpp2 type declaration, mark it for differentiation. + add_for_differentiation(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(type_decls), 0)); + + // Add the AD suffix to the type + type_d += rws_suffix; + } + } + + // Replace with AD type for the AD order. + return string_util::replace_all(cpp2::move(type_d), "double", rws_ad_type); + } + +#line 4181 "reflect.h2" + [[nodiscard]] auto autodiff_context::get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style{ + // TODO: inspect does not work here: error: error: no matching function for call to ‘is(const cpp2::passing_style&)’ + // return inspect p -> passing_style { + // is passing_style::in = passing_style::inout; + // is passing_style::in_ref = passing_style::inout; + // is passing_style::copy = passing_style::inout; + // is passing_style::inout = passing_style::inout; + // is passing_style::out = passing_style::inout; + // is passing_style::move = passing_style::inout; + // is passing_style::forward = passing_style::inout; + // is passing_style::forward_ref = passing_style::inout; + // is _ = passing_style::inout; + // }; + if (p == passing_style::in) { return passing_style::inout; } + if (p == passing_style::in_ref) { return passing_style::inout; } + if (p == passing_style::copy) { return passing_style::inout; } + if (p == passing_style::inout) { return passing_style::inout; } + if (p == passing_style::out) { return passing_style::inout; } + if (p == passing_style::move) { return passing_style::inout; } + if (p == passing_style::forward) { return passing_style::inout; } + if (p == passing_style::forward_ref) { return passing_style::inout; } + +#line 4204 "reflect.h2" + CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Do not know how to handle passing style:" + cpp2::to_string(p) + ""); + + return passing_style::inout; + } + +#line 4209 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4162 "reflect.h2" +#line 4210 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -7921,7 +7987,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4184 "reflect.h2" +#line 4232 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ if (name == "_") { return autodiff_declared_variable(name, "_", false); @@ -7939,10 +8005,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return autodiff_declared_variable(); } -#line 4201 "reflect.h2" +#line 4249 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4202 "reflect.h2" +#line 4250 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7952,10 +8018,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4211 "reflect.h2" +#line 4259 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ std::vector r {}; -#line 4212 "reflect.h2" +#line 4260 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); @@ -7965,10 +8031,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4221 "reflect.h2" +#line 4269 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4222 "reflect.h2" +#line 4270 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -7978,12 +8044,12 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4231 "reflect.h2" +#line 4279 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4232 "reflect.h2" +#line 4280 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -8005,7 +8071,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4253 "reflect.h2" +#line 4301 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -8014,7 +8080,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4261 "reflect.h2" +#line 4309 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -8035,7 +8101,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4281 "reflect.h2" +#line 4329 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -8046,18 +8112,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4291 "reflect.h2" +#line 4339 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4296 "reflect.h2" +#line 4344 "reflect.h2" auto autodiff_context::leave_function() & -> void{ CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4300 "reflect.h2" +#line 4348 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -8071,7 +8137,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4313 "reflect.h2" +#line 4361 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -8087,95 +8153,106 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4328 "reflect.h2" +#line 4376 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4341 "reflect.h2" +#line 4389 "reflect.h2" autodiff_diff_code::autodiff_diff_code(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4343 "reflect.h2" +#line 4391 "reflect.h2" } -#line 4341 "reflect.h2" +#line 4389 "reflect.h2" auto autodiff_diff_code::operator=(autodiff_context* ctx_) -> autodiff_diff_code& { ctx = ctx_; fwd = ""; rws = ""; return *this; -#line 4343 "reflect.h2" +#line 4391 "reflect.h2" + } + +#line 4393 "reflect.h2" + auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v; }} +#line 4394 "reflect.h2" + auto autodiff_diff_code::add_reverse(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws += v; }} + +#line 4396 "reflect.h2" + auto autodiff_diff_code::reset() & -> void{ + fwd = ""; + rws = ""; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4346 "reflect.h2" +#line 4402 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; rws = ""; return *this; -#line 4349 "reflect.h2" +#line 4405 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4352 "reflect.h2" +#line 4408 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4357 "reflect.h2" +#line 4413 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4362 "reflect.h2" +#line 4418 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4367 "reflect.h2" +#line 4423 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4377 "reflect.h2" +#line 4433 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4380 "reflect.h2" +#line 4436 "reflect.h2" } -#line 4377 "reflect.h2" +#line 4433 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4380 "reflect.h2" +#line 4436 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4383 "reflect.h2" +#line 4439 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff += o.diff.fwd; } -#line 4397 "reflect.h2" +#line 4453 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4399 "reflect.h2" +#line 4455 "reflect.h2" } -#line 4401 "reflect.h2" +#line 4457 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8185,30 +8262,30 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4410 "reflect.h2" +#line 4466 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4414 "reflect.h2" +#line 4470 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } -#line 4416 "reflect.h2" +#line 4472 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } -#line 4420 "reflect.h2" +#line 4476 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; } -#line 4424 "reflect.h2" +#line 4480 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4426 "reflect.h2" +#line 4482 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4428 "reflect.h2" +#line 4484 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } @@ -8218,7 +8295,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8228,7 +8305,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} return args; } -#line 4447 "reflect.h2" +#line 4503 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8280,7 +8357,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} }} } -#line 4498 "reflect.h2" +#line 4554 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8288,7 +8365,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} { auto i{0}; -#line 4504 "reflect.h2" +#line 4560 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8302,7 +8379,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4516 "reflect.h2" +#line 4572 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8325,7 +8402,7 @@ auto i{0}; { auto i{0}; -#line 4537 "reflect.h2" +#line 4593 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8350,7 +8427,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4560 "reflect.h2" +#line 4616 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8433,7 +8510,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4642 "reflect.h2" +#line 4698 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8456,7 +8533,7 @@ auto i{0}; { auto i{1}; -#line 4663 "reflect.h2" +#line 4719 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8466,69 +8543,69 @@ auto i{1}; } } -#line 4671 "reflect.h2" +#line 4727 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4677 "reflect.h2" +#line 4733 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4681 "reflect.h2" +#line 4737 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4685 "reflect.h2" +#line 4741 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4689 "reflect.h2" +#line 4745 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4693 "reflect.h2" +#line 4749 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4697 "reflect.h2" +#line 4753 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4701 "reflect.h2" +#line 4757 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4705 "reflect.h2" +#line 4761 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4709 "reflect.h2" +#line 4765 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4713 "reflect.h2" +#line 4769 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4717 "reflect.h2" +#line 4773 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4721 "reflect.h2" +#line 4777 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8553,7 +8630,7 @@ auto i{1}; fwd_expr = cpp2::move(fwd); } -#line 4745 "reflect.h2" +#line 4801 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8594,7 +8671,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4786 "reflect.h2" +#line 4842 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8611,12 +8688,12 @@ auto i{1}; } } -#line 4802 "reflect.h2" +#line 4858 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4806 "reflect.h2" +#line 4862 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -8633,7 +8710,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 4822 "reflect.h2" +#line 4878 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8642,7 +8719,7 @@ auto i{1}; { auto i{0}; -#line 4829 "reflect.h2" +#line 4885 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8657,7 +8734,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4842 "reflect.h2" +#line 4898 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8678,7 +8755,7 @@ auto i{0}; } } -#line 4862 "reflect.h2" +#line 4918 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8711,26 +8788,26 @@ auto i{0}; }}}} } -#line 4903 "reflect.h2" +#line 4959 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4906 "reflect.h2" +#line 4962 "reflect.h2" } -#line 4908 "reflect.h2" +#line 4964 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4913 "reflect.h2" +#line 4969 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4918 "reflect.h2" +#line 4974 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8759,22 +8836,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 4947 "reflect.h2" +#line 5003 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4952 "reflect.h2" +#line 5008 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 4957 "reflect.h2" +#line 5013 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 4962 "reflect.h2" +#line 5018 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8782,7 +8859,7 @@ auto i{0}; diff += "}\n"; } -#line 4970 "reflect.h2" +#line 5026 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8799,7 +8876,7 @@ auto i{0}; } } -#line 4987 "reflect.h2" +#line 5043 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8849,7 +8926,7 @@ auto i{0}; }} } -#line 5037 "reflect.h2" +#line 5093 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8861,12 +8938,12 @@ auto i{0}; } } -#line 5048 "reflect.h2" +#line 5104 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5052 "reflect.h2" +#line 5108 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8880,73 +8957,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 5065 "reflect.h2" +#line 5121 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5069 "reflect.h2" +#line 5125 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5073 "reflect.h2" +#line 5129 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5077 "reflect.h2" +#line 5133 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5081 "reflect.h2" +#line 5137 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5085 "reflect.h2" +#line 5141 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5089 "reflect.h2" +#line 5145 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5093 "reflect.h2" +#line 5149 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5097 "reflect.h2" +#line 5153 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5101 "reflect.h2" +#line 5157 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5105 "reflect.h2" +#line 5161 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5109 "reflect.h2" +#line 5165 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5113 "reflect.h2" +#line 5169 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5118 "reflect.h2" +#line 5174 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8955,7 +9032,7 @@ auto i{0}; { auto i{0}; -#line 5125 "reflect.h2" +#line 5181 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8970,7 +9047,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5138 "reflect.h2" +#line 5194 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8983,31 +9060,32 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5150 "reflect.h2" +#line 5206 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5167 "reflect.h2" +#line 5223 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5170 "reflect.h2" +#line 5226 "reflect.h2" } -#line 5172 "reflect.h2" +#line 5228 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5177 "reflect.h2" +#line 5233 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); - diff = " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": ("; + CPP2_UFCS(add_forward)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": ("); + CPP2_UFCS(add_reverse)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": ("); // 1. Generate the modified signature // a) Parameters @@ -9015,46 +9093,104 @@ auto i{0}; for ( auto const& param : CPP2_UFCS(get_parameters)(f) ) { std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; + auto fwd_pass_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; + auto rws_pass_style {to_string_view(CPP2_UFCS(get_reverse_passing_style)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_passing_style)(param)))}; + if ("this" == name) { auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), std::string(CPP2_UFCS(name)(decl)))}; - diff += "" + cpp2::to_string(name) + ", "; - diff += "" + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(cpp2::move(fwd_ad_type)) + ", "; + auto rws_ad_type {CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), std::string(CPP2_UFCS(name)(decl)))}; + + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + ", "); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(fwd_ad_type) + ", "); + + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + ", "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) {// Add forward type for higher order + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(cpp2::move(fwd_ad_type)) + ", "); + } + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(cpp2::move(rws_ad_type)) + ", "); } else { auto type {CPP2_UFCS(get_declaration)(param).type()}; - diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "; - diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + } + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); +#line 5273 "reflect.h2" CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type)); } } - diff += ") -> ("; + // b) Add arguments for returns that become inputs + + if (CPP2_UFCS(has_non_void_return_type)(f) && CPP2_UFCS(empty)(CPP2_UFCS(get_returns)(f))) {// TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) + if (CPP2_UFCS(has_deduced_return_type)(f)) { + // TODO: Take care of initialization order error. + CPP2_UFCS(add_reverse)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ", "); + } + else { + CPP2_UFCS(add_reverse)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + ", "); + } + } + else { + for ( auto const& param : CPP2_UFCS(get_returns)(f) ) { + auto name {CPP2_UFCS(get_declaration)(param).name()}; + auto type {CPP2_UFCS(get_declaration)(param).type()}; + + auto rws_pass_style {to_string_view(CPP2_UFCS(get_reverse_passing_style)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_passing_style)(param)))}; + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type))) + " , "); + } + } + + CPP2_UFCS(add_forward)(diff, ") -> ("); + CPP2_UFCS(add_reverse)(diff, ") -> ("); - // b) Returns + // c) Returns if (CPP2_UFCS(has_non_void_return_type)(f) && CPP2_UFCS(empty)(CPP2_UFCS(get_returns)(f))) {// TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if (CPP2_UFCS(has_deduced_return_type)(f)) { // TODO: Take care of initialization order error. - diff += "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ", "; + CPP2_UFCS(add_forward)(diff, "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ", "); + CPP2_UFCS(add_reverse)(diff, "r, "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ","); + } } else { - diff += "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "; + CPP2_UFCS(add_forward)(diff, "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "); + CPP2_UFCS(add_reverse)(diff, "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "); + } } } else { for ( auto const& param : CPP2_UFCS(get_returns)(f) ) { auto name {CPP2_UFCS(get_declaration)(param).name()}; auto type {CPP2_UFCS(get_declaration)(param).type()}; - diff += "" + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "; - diff += "" + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "; + + auto fwd_pass_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; + auto rws_pass_style {to_string_view(CPP2_UFCS(get_reverse_passing_style)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_passing_style)(param)))}; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); + + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); + } CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + ""); } } - diff += ") = {"; + CPP2_UFCS(add_forward)(diff, ") = {"); + CPP2_UFCS(add_reverse)(diff, ") = {"); // Generate the body @@ -9063,27 +9199,34 @@ auto i{0}; return ; } -#line 5237 "reflect.h2" +#line 5352 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5240 "reflect.h2" +#line 5355 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); } - diff += cpp2::move(ad_impl).diff; + CPP2_UFCS(add_forward)(diff, ad_impl.diff.fwd); + CPP2_UFCS(add_reverse)(diff, cpp2::move(ad_impl).diff.rws); - diff += "}"; + CPP2_UFCS(add_forward)(diff, "}"); + CPP2_UFCS(add_reverse)(diff, "}"); CPP2_UFCS(leave_function)((*cpp2::impl::assert_not_null(ctx))); - CPP2_UFCS(add_member)(decl, diff.fwd); - diff = ""; + if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_member)(decl, diff.fwd); + } + if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_member)(decl, diff.rws); + } + CPP2_UFCS(reset)(diff); CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5257 "reflect.h2" +#line 5379 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9111,7 +9254,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5285 "reflect.h2" +#line 5407 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9135,17 +9278,17 @@ auto i{0}; } } -#line 5309 "reflect.h2" +#line 5431 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5314 "reflect.h2" +#line 5436 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5320 "reflect.h2" +#line 5442 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9321,7 +9464,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5405 "reflect.h2" +#line 5527 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9337,11 +9480,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5421 "reflect.h2" +#line 5543 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5425 "reflect.h2" +#line 5547 "reflect.h2" // mod: i // mod: m // mod: s @@ -9349,116 +9492,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5434 "reflect.h2" +#line 5556 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5443 "reflect.h2" +#line 5565 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5445 "reflect.h2" +#line 5567 "reflect.h2" } -#line 5447 "reflect.h2" +#line 5569 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5449 "reflect.h2" +#line 5571 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5455 "reflect.h2" +#line 5577 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5456 "reflect.h2" +#line 5578 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5457 "reflect.h2" +#line 5579 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5472 "reflect.h2" +#line 5594 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5475 "reflect.h2" +#line 5597 "reflect.h2" } -#line 5477 "reflect.h2" +#line 5599 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5481 "reflect.h2" +#line 5603 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5493 "reflect.h2" +#line 5615 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5496 "reflect.h2" +#line 5618 "reflect.h2" } -#line 5498 "reflect.h2" +#line 5620 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5502 "reflect.h2" +#line 5624 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5512 "reflect.h2" +#line 5634 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5514 "reflect.h2" +#line 5636 "reflect.h2" } -#line 5516 "reflect.h2" +#line 5638 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5520 "reflect.h2" +#line 5642 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5532 "reflect.h2" +#line 5654 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5535 "reflect.h2" +#line 5657 "reflect.h2" } -#line 5537 "reflect.h2" +#line 5659 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5543 "reflect.h2" +#line 5665 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5549 "reflect.h2" +#line 5671 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9467,7 +9610,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5557 "reflect.h2" +#line 5679 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9483,7 +9626,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5585 "reflect.h2" +#line 5707 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9491,14 +9634,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5593 "reflect.h2" +#line 5715 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5600 "reflect.h2" +#line 5722 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9510,15 +9653,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5612 "reflect.h2" +#line 5734 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5617 "reflect.h2" +#line 5739 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5621 "reflect.h2" +#line 5743 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9539,7 +9682,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5647 "reflect.h2" +#line 5769 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9548,20 +9691,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5656 "reflect.h2" +#line 5778 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5662 "reflect.h2" +#line 5784 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5669 "reflect.h2" +#line 5791 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9576,16 +9719,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5699 "reflect.h2" +#line 5821 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5703 "reflect.h2" +#line 5825 "reflect.h2" } -#line 5709 "reflect.h2" +#line 5831 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9595,7 +9738,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5719 "reflect.h2" +#line 5841 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9603,17 +9746,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5726 "reflect.h2" +#line 5848 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5730 "reflect.h2" +#line 5852 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5737 "reflect.h2" +#line 5859 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9623,7 +9766,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5746 "reflect.h2" +#line 5868 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9631,24 +9774,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5753 "reflect.h2" +#line 5875 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5761 "reflect.h2" +#line 5883 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5765 "reflect.h2" +#line 5887 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5769 "reflect.h2" +#line 5891 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9660,22 +9803,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5780 "reflect.h2" +#line 5902 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5786 "reflect.h2" +#line 5908 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5790 "reflect.h2" +#line 5912 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5794 "reflect.h2" +#line 5916 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9683,7 +9826,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5801 "reflect.h2" +#line 5923 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9695,10 +9838,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5814 "reflect.h2" +#line 5936 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5817 "reflect.h2" +#line 5939 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9738,7 +9881,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5857 "reflect.h2" +#line 5979 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9750,14 +9893,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5868 "reflect.h2" +#line 5990 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5869 "reflect.h2" +#line 5991 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5870 "reflect.h2" +#line 5992 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5872 "reflect.h2" +#line 5994 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9767,10 +9910,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5881 "reflect.h2" +#line 6003 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 5883 "reflect.h2" +#line 6005 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9792,14 +9935,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5904 "reflect.h2" +#line 6026 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 5905 "reflect.h2" +#line 6027 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 5906 "reflect.h2" +#line 6028 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 5908 "reflect.h2" +#line 6030 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9813,7 +9956,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5921 "reflect.h2" +#line 6043 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9835,7 +9978,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 5942 "reflect.h2" +#line 6064 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9846,12 +9989,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5952 "reflect.h2" +#line 6074 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 5953 "reflect.h2" +#line 6075 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 5958 "reflect.h2" +#line 6080 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -9906,7 +10049,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6012 "reflect.h2" +#line 6134 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -9946,7 +10089,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6051 "reflect.h2" +#line 6173 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -9962,21 +10105,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6068 "reflect.h2" +#line 6190 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6069 "reflect.h2" +#line 6191 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6070 "reflect.h2" +#line 6192 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6072 "reflect.h2" +#line 6194 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6087 "reflect.h2" +#line 6209 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -9984,7 +10127,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6094 "reflect.h2" +#line 6216 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -9994,22 +10137,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6112 "reflect.h2" +#line 6234 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6117 "reflect.h2" +#line 6239 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6123 "reflect.h2" +#line 6245 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6129 "reflect.h2" +#line 6251 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10018,7 +10161,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6137 "reflect.h2" +#line 6259 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10030,7 +10173,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6148 "reflect.h2" +#line 6270 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10038,7 +10181,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6155 "reflect.h2" +#line 6277 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10059,7 +10202,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6176 "reflect.h2" +#line 6298 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10069,7 +10212,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6186 "reflect.h2" +#line 6308 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10092,33 +10235,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6210 "reflect.h2" +#line 6332 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6216 "reflect.h2" +#line 6338 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6220 "reflect.h2" +#line 6342 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6226 "reflect.h2" +#line 6348 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6234 "reflect.h2" +#line 6356 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10127,7 +10270,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6242 "reflect.h2" +#line 6364 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10136,22 +10279,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6252 "reflect.h2" +#line 6374 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6256 "reflect.h2" +#line 6378 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6260 "reflect.h2" +#line 6382 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6264 "reflect.h2" +#line 6386 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10175,18 +10318,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6289 "reflect.h2" +#line 6411 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6304 "reflect.h2" +#line 6426 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6306 "reflect.h2" +#line 6428 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10197,15 +10340,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6321 "reflect.h2" +#line 6443 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6324 "reflect.h2" +#line 6446 "reflect.h2" } -#line 6326 "reflect.h2" +#line 6448 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10223,7 +10366,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6343 "reflect.h2" +#line 6465 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10231,7 +10374,7 @@ generation_function_context::generation_function_context(){} } } -#line 6350 "reflect.h2" +#line 6472 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10245,7 +10388,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6363 "reflect.h2" +#line 6485 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10261,14 +10404,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6384 "reflect.h2" +#line 6506 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6386 "reflect.h2" +#line 6508 "reflect.h2" } -#line 6388 "reflect.h2" +#line 6510 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10277,11 +10420,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6403 "reflect.h2" +#line 6525 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6405 "reflect.h2" +#line 6527 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10289,7 +10432,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6412 "reflect.h2" +#line 6534 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10298,37 +10441,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6420 "reflect.h2" +#line 6542 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6434 "reflect.h2" +#line 6556 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6438 "reflect.h2" +#line 6560 "reflect.h2" } -#line 6440 "reflect.h2" +#line 6562 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6444 "reflect.h2" +#line 6566 "reflect.h2" } -#line 6446 "reflect.h2" +#line 6568 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6450 "reflect.h2" +#line 6572 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10337,14 +10480,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6456 "reflect.h2" +#line 6578 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6461 "reflect.h2" +#line 6583 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10357,7 +10500,7 @@ size_t i{0}; } } -#line 6473 "reflect.h2" +#line 6595 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10379,7 +10522,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6494 "reflect.h2" +#line 6616 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10398,7 +10541,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6512 "reflect.h2" +#line 6634 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10414,14 +10557,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6527 "reflect.h2" +#line 6649 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6533 "reflect.h2" +#line 6655 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10429,19 +10572,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6550 "reflect.h2" +#line 6672 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6551 "reflect.h2" +#line 6673 "reflect.h2" { -#line 6556 "reflect.h2" +#line 6678 "reflect.h2" } -#line 6559 "reflect.h2" +#line 6681 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10567,7 +10710,7 @@ size_t i{0}; ); } -#line 6684 "reflect.h2" +#line 6806 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10577,13 +10720,13 @@ size_t i{0}; ); } -#line 6693 "reflect.h2" +#line 6815 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6698 "reflect.h2" +#line 6820 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10594,12 +10737,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6710 "reflect.h2" +#line 6832 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6715 "reflect.h2" +#line 6837 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10633,7 +10776,7 @@ size_t i{0}; } -#line 6751 "reflect.h2" +#line 6873 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10642,19 +10785,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6774 "reflect.h2" +#line 6896 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6775 "reflect.h2" +#line 6897 "reflect.h2" { -#line 6780 "reflect.h2" +#line 6902 "reflect.h2" } -#line 6782 "reflect.h2" +#line 6904 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10756,19 +10899,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 6883 "reflect.h2" +#line 7005 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 6887 "reflect.h2" +#line 7009 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 6911 "reflect.h2" +#line 7033 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10787,7 +10930,7 @@ size_t i{0}; return r; } -#line 6929 "reflect.h2" +#line 7051 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10802,7 +10945,7 @@ size_t i{0}; return r; } -#line 6943 "reflect.h2" +#line 7065 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -10962,7 +11105,7 @@ size_t i{0}; } } -#line 7102 "reflect.h2" +#line 7224 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -10971,7 +11114,7 @@ size_t i{0}; return r; } -#line 7110 "reflect.h2" +#line 7232 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -10990,7 +11133,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7128 "reflect.h2" +#line 7250 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11022,7 +11165,7 @@ size_t i{0}; } } -#line 7159 "reflect.h2" +#line 7281 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11033,7 +11176,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7171 "reflect.h2" +#line 7293 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11072,7 +11215,7 @@ size_t i{0}; return r; } -#line 7212 "reflect.h2" +#line 7334 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11090,7 +11233,7 @@ size_t i{0}; }} } -#line 7232 "reflect.h2" +#line 7354 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11104,16 +11247,16 @@ size_t i{0}; } } -#line 7258 "reflect.h2" +#line 7380 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7261 "reflect.h2" +#line 7383 "reflect.h2" } -#line 7263 "reflect.h2" +#line 7385 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11125,7 +11268,7 @@ size_t i{0}; } } -#line 7274 "reflect.h2" +#line 7396 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11133,14 +11276,14 @@ size_t i{0}; return r; } -#line 7281 "reflect.h2" +#line 7403 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7289 "reflect.h2" +#line 7411 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11166,7 +11309,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7317 "reflect.h2" +#line 7439 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11192,11 +11335,11 @@ size_t i{0}; return r; } -#line 7354 "reflect.h2" +#line 7476 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7356 "reflect.h2" +#line 7478 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11270,7 +11413,7 @@ size_t i{0}; return nullptr; } -#line 7429 "reflect.h2" +#line 7551 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11283,7 +11426,7 @@ size_t i{0}; }} } -#line 7441 "reflect.h2" +#line 7563 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11297,7 +11440,7 @@ size_t i{0}; }} } -#line 7454 "reflect.h2" +#line 7576 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11317,7 +11460,7 @@ size_t i{0}; return r; } -#line 7473 "reflect.h2" +#line 7595 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11328,7 +11471,7 @@ size_t i{0}; return r; } -#line 7483 "reflect.h2" +#line 7605 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11340,14 +11483,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7494 "reflect.h2" +#line 7616 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7506 "reflect.h2" +#line 7628 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11371,7 +11514,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7530 "reflect.h2" +#line 7652 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11381,7 +11524,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7542 "reflect.h2" +#line 7664 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11397,7 +11540,7 @@ size_t i{0}; } } -#line 7562 "reflect.h2" +#line 7684 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11415,15 +11558,15 @@ size_t i{0}; }} } -#line 7598 "reflect.h2" +#line 7720 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7601 "reflect.h2" +#line 7723 "reflect.h2" } -#line 7603 "reflect.h2" +#line 7725 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11459,7 +11602,7 @@ size_t i{0}; return source; } -#line 7638 "reflect.h2" +#line 7760 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11475,7 +11618,7 @@ size_t i{0}; } } -#line 7654 "reflect.h2" +#line 7776 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11484,7 +11627,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11539,7 +11682,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7723 "reflect.h2" +#line 7845 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11661,7 +11804,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7845 "reflect.h2" +#line 7967 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index d9bab81a6..7ae4558f1 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4133,7 +4133,9 @@ autodiff_context: type = { _ = declaration_stack.push_back(autodiff_declaration_stack_item(full_name, t)); } - is_taylor: (this) = order != 1; + is_forward: (this) = !reverse || (reverse && order != 1); + is_reverse: (this) = reverse; + is_taylor : (this) = order != 1; gen_temporary : (inout this) -> std::string = { temporary_count += 1; @@ -4158,6 +4160,52 @@ autodiff_context: type = { return string_util::replace_all(type_d, "double", fwd_ad_type); } + get_rws_ad_type: (inout this, type: std::string) -> std::string = { + type_d := type; + + if "double" != type { + type_decls := lookup_type_declaration(type); + if !type_decls.empty() { + // We found a cpp2 type declaration, mark it for differentiation. + add_for_differentiation(type_decls[0]); + + // Add the AD suffix to the type + type_d += rws_suffix; + } + } + + // Replace with AD type for the AD order. + return string_util::replace_all(type_d, "double", rws_ad_type); + } + + get_reverse_passing_style: (this, p: passing_style) -> passing_style = { + // TODO: inspect does not work here: error: error: no matching function for call to ‘is(const cpp2::passing_style&)’ + // return inspect p -> passing_style { + // is passing_style::in = passing_style::inout; + // is passing_style::in_ref = passing_style::inout; + // is passing_style::copy = passing_style::inout; + // is passing_style::inout = passing_style::inout; + // is passing_style::out = passing_style::inout; + // is passing_style::move = passing_style::inout; + // is passing_style::forward = passing_style::inout; + // is passing_style::forward_ref = passing_style::inout; + // is _ = passing_style::inout; + // }; + if p == passing_style::in { return passing_style::inout; } + if p == passing_style::in_ref { return passing_style::inout; } + if p == passing_style::copy { return passing_style::inout; } + if p == passing_style::inout { return passing_style::inout; } + if p == passing_style::out { return passing_style::inout; } + if p == passing_style::move { return passing_style::inout; } + if p == passing_style::forward { return passing_style::inout; } + if p == passing_style::forward_ref { return passing_style::inout; } + + + declaration_stack.back().decl.error("AD: Do not know how to handle passing style:(p)$"); + + return passing_style::inout; + } + lookup_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { for std::ranges::views::reverse(declaration_stack) do (cur) { @@ -4342,6 +4390,14 @@ autodiff_diff_code: type = { ctx = ctx_; } + add_forward: (inout this, v: std::string) = { if ctx*.is_forward() { fwd += v; }} + add_reverse: (inout this, v: std::string) = { if ctx*.is_reverse() { rws += v; }} + + reset: (inout this) = { + fwd = ""; + rws = ""; + } + // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. operator=:(inout this, v: std::string) = { ctx = ctx; @@ -5177,54 +5233,113 @@ autodiff_declaration_handler: type = { traverse: (override inout this, f: meta::function_declaration) = { ctx*.enter_function(); - diff = " (f.name())$(ctx*.fwd_suffix)$: ("; + diff.add_forward(" (f.name())$(ctx*.fwd_suffix)$: ("); + diff.add_reverse(" (f.name())$(ctx*.rws_suffix)$: ("); // 1. Generate the modified signature // a) Parameters for f.get_parameters() do (param) { - name : std::string = param.get_declaration().name(); + name: std::string = param.get_declaration().name(); - if "this" == name{ + fwd_pass_style := to_string_view(param.get_passing_style()); + rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); + + if "this" == name { fwd_ad_type := ctx*.get_fwd_ad_type(std::string(decl.name())); - diff += "(name)$, "; - diff += "(name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "; + rws_ad_type := ctx*.get_rws_ad_type(std::string(decl.name())); + + diff.add_forward("(fwd_pass_style)$ (name)$, "); + diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "); + + diff.add_reverse("(fwd_pass_style)$ (name)$, "); + if ctx*.is_taylor() { // Add forward type for higher order + diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "); + } + diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$: (rws_ad_type)$, "); } else { type := param.get_declaration().type(); - diff += "(name)$ : (type)$, "; - diff += "(name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "; + diff.add_forward("(fwd_pass_style)$ (name)$ : (type)$, "); + diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); + + diff.add_reverse("(fwd_pass_style)$ (name)$ : (type)$, "); + if ctx*.is_taylor() { + diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); + } + diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$, "); + ctx*.add_variable_declaration(name, type); } } - diff += ") -> ("; + // b) Add arguments for returns that become inputs - // b) Returns + if f.has_non_void_return_type() && f.get_returns().empty() { // TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? + // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) + if f.has_deduced_return_type() { + // TODO: Take care of initialization order error. + diff.add_reverse("inout r(ctx*.rws_suffix)$, "); + } + else { + diff.add_reverse("inout r(ctx*.rws_suffix)$: (ctx*.get_rws_ad_type(f.get_unnamed_return_type()))$, "); + } + } + else { + for f.get_returns() do (param) { + name := param.get_declaration().name(); + type := param.get_declaration().type(); + + rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); + diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$ , "); + } + } + + diff.add_forward(") -> ("); + diff.add_reverse(") -> ("); + + // c) Returns if f.has_non_void_return_type() && f.get_returns().empty() { // TODO: has_non_void_return_type is true for return lists: (r: double) bug/feature? // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if f.has_deduced_return_type() { // TODO: Take care of initialization order error. - diff += "r, r(ctx*.fwd_suffix)$, "; + diff.add_forward("r, r(ctx*.fwd_suffix)$, "); + diff.add_reverse("r, "); + if ctx*.is_taylor() { + diff.add_reverse("r(ctx*.fwd_suffix)$,"); + } } else { - diff += "r: (f.get_unnamed_return_type())$ = (), r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "; + diff.add_forward("r: (f.get_unnamed_return_type())$ = (), r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "); + diff.add_reverse("r: (f.get_unnamed_return_type())$ = (), "); + if ctx*.is_taylor() { + diff.add_reverse("r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "); + } } } else { for f.get_returns() do (param) { name := param.get_declaration().name(); type := param.get_declaration().type(); - diff += "(name)$ : (param.get_declaration().type())$ = 0.0, "; - diff += "(name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "; + + fwd_pass_style := to_string_view(param.get_passing_style()); + rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); + diff.add_forward("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); + diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); + + diff.add_reverse("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); + if ctx*.is_taylor() { + diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); + } ctx*.add_variable_declaration("(name)$", "(type)$"); } } - diff += ") = {"; + diff.add_forward(") = {"); + diff.add_reverse(") = {"); // Generate the body @@ -5241,14 +5356,21 @@ autodiff_declaration_handler: type = { { ad_impl..pre_traverse(stmt); } - diff += ad_impl.diff; + diff.add_forward(ad_impl.diff.fwd); + diff.add_reverse(ad_impl.diff.rws); - diff += "}"; + diff.add_forward("}"); + diff.add_reverse("}"); ctx*.leave_function(); - decl.add_member( diff.fwd ); - diff = ""; + if ctx*.is_forward() { + decl.add_member( diff.fwd ); + } + if ctx*.is_reverse() { + decl.add_member( diff.rws ); + } + diff.reset(); ctx*.add_as_differentiated(f); } From beb3629e2e7a407abceeb9e3fb3f7a3a94a41509 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 25 Aug 2025 16:56:41 +0200 Subject: [PATCH 41/54] Reverse differentiation of additive expressions. --- include/cpp2taylor.h2 | 12 ++++ source/reflect.h2 | 125 +++++++++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 50 deletions(-) diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index 879689e60..eb1654fa5 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -54,6 +54,18 @@ taylor: type = { return v[i - 1]; } + // Overload for reverse AD. + operator+=: (inout this, o: taylor) -> forward_ref _ = { + this = this + o; + return this; + } + + // Overload for reverse AD. + operator-=: (inout this, o: taylor) -> forward_ref _ = { + this = this - o; + return this; + } + // Overload for simple handling of connected adds. operator+: (this, o: taylor) -> taylor = { return add(o, 0.0, 0.0); // Primal values are not required. diff --git a/source/reflect.h2 b/source/reflect.h2 index 7ae4558f1..5bf87121c 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4383,19 +4383,22 @@ autodiff_context: type = { autodiff_diff_code: type = { public ctx: *autodiff_context; - public fwd: std::string = ""; - public rws: std::string = ""; + public fwd : std::string = ""; + public rws_primal : std::string = ""; + public rws_backprop: std::string = ""; operator=:(out this, ctx_: *autodiff_context) = { ctx = ctx_; } - add_forward: (inout this, v: std::string) = { if ctx*.is_forward() { fwd += v; }} - add_reverse: (inout this, v: std::string) = { if ctx*.is_reverse() { rws += v; }} + add_forward : (inout this, v: std::string) = { if ctx*.is_forward() { fwd += v; }} + add_reverse_primal : (inout this, v: std::string) = { if ctx*.is_reverse() { rws_primal += v; }} + add_reverse_backprop: (inout this, v: std::string) = { if ctx*.is_reverse() { rws_backprop += v; }} reset: (inout this) = { - fwd = ""; - rws = ""; + fwd = ""; + rws_primal = ""; + rws_backprop = ""; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. @@ -4437,7 +4440,9 @@ autodiff_handler_base: type = { // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. append: (inout this, in_ref o: autodiff_handler_base) = { - diff += o.diff.fwd; + diff.fwd += o.diff.fwd; + diff.rws_primal += o.diff.rws_primal; + diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } } @@ -4449,28 +4454,35 @@ autodiff_expression_handler: type = { public primal_expr: std::string = ""; public fwd_expr : std::string = ""; + public rws_expr : std::string = ""; operator=: (out this, ctx_: *autodiff_context) = { autodiff_handler_base = (ctx_); } - add_suffix_if_not_wildcard: (this, lhs: std::string) -> std::string = { + add_suffix_if_not_wildcard: (this, lhs: std::string, suffix: std::string) -> std::string = { if "_" == lhs { return lhs; } else { - return lhs + ctx*.fwd_suffix; + return lhs + suffix; } } - gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string) = { - diff += "(lhs_d)$ = (rhs_d)$;\n"; - diff += "(lhs)$ = (rhs)$;\n"; + gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string) = { + diff.add_forward("(lhs_d)$ = (rhs_d)$;\n"); + diff.add_forward("(lhs)$ = (rhs)$;\n"); + + if ctx*.is_taylor() { + diff.add_reverse_primal("(lhs_d)$ = (rhs_d)$;\n"); + } + diff.add_reverse_primal("(lhs)$ = (rhs)$;\n"); + diff.add_reverse_backprop(string_util::replace_all(rhs_b, "_rb_", lhs_b)); } - gen_assignment: (inout this, lhs: std::string, lhs_d: std::string) - = gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); + gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string) + = gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); gen_assignment: (inout this, lhs: std::string) - = gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); + = gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, ctx*.fwd_suffix), add_suffix_if_not_wildcard(lhs, ctx*.rws_suffix), primal_expr, fwd_expr, rws_expr); gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string, type_d: std::string) = { @@ -4486,13 +4498,14 @@ autodiff_expression_handler: type = { - primal_fwd_name: @struct type = { + primal_fwd_rws_name: @struct type = { primal: std::string = ""; fwd : std::string = ""; + rws : std::string = ""; } - handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { - args : std::vector = (); + handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { + args : std::vector = (); for list.get_expressions() do (expr) { args.push_back(handle_expression_term(expr)); } @@ -4500,29 +4513,31 @@ autodiff_expression_handler: type = { return args; } - handle_expression_term :(inout this, term) -> primal_fwd_name = { + handle_expression_term :(inout this, term) -> primal_fwd_rws_name = { if term.is_identifier() { primal := term.to_string(); fwd := primal + ctx*.fwd_suffix; + rws := primal + ctx*.rws_suffix; decl := ctx*.lookup_variable_declaration(primal); if decl.is_member { fwd = "this(ctx*.fwd_suffix)$." + fwd; + rws = "this(ctx*.rws_suffix)$." + rws; } - return (primal, fwd); + return (primal, fwd, rws); } else if term.is_expression_list() { exprs := term..as_expression_list()..get_expressions(); if exprs.ssize() != 1 { term.error("Can not handle multiple expressions. (term.to_string())"); - return ("error", ""); + return ("error", "", ""); } expr := exprs[0]; bin_expr := expr..as_assignment_expression(); if bin_expr.terms_size() != 0 { term.error("Can not handle assign expr inside of expression. (expr.to_string())$"); - return ("error", ""); + return ("error", "", ""); } ad : autodiff_expression_handler = (ctx); @@ -4531,7 +4546,7 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - r : primal_fwd_name = (t, t + ctx*.fwd_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + r : primal_fwd_rws_name = (t, t + ctx*.fwd_suffix, t + ctx*.rws_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) _ = t; return r; } @@ -4545,7 +4560,7 @@ autodiff_expression_handler: type = { ad.gen_declaration(t, "double"); // TODO: get type of expression append(ad); - r : primal_fwd_name = (t, t + ctx*.fwd_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + r : primal_fwd_rws_name = (t, t + ctx*.fwd_suffix, t + ctx*.rws_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) _ = t; return r; } @@ -4577,7 +4592,7 @@ autodiff_expression_handler: type = { object : std::string = ""; object_d : std::string = ""; function_name : std::string = ""; - args : std::vector = (); + args : std::vector = (); primary := postfix.get_primary_expression(); @@ -4695,7 +4710,7 @@ autodiff_expression_handler: type = { // TODO: Add function to list of functions/objects for differentiation for the no return case. } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { + handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !object.empty()); @@ -4778,17 +4793,21 @@ autodiff_expression_handler: type = { terms := binexpr.get_terms(); first := true; + op : std::string = "+"; fwd : std::string = ""; + rws : std::string = ""; primal: std::string = ""; for terms do (term) { if !first { - op := term.get_op().to_string(); + op = term.get_op().to_string(); fwd += " (op)$ "; primal += " (op)$ "; + } var := handle_expression_term(term.get_term()); fwd += var.fwd; + rws += "(var.rws)$ (op)$= _rb_;\n"; primal += var.primal; first = false; @@ -4796,6 +4815,7 @@ autodiff_expression_handler: type = { primal_expr = primal; fwd_expr = fwd; + rws_expr = rws; } traverse: (override inout this, binexpr: meta::multiplicative_expression) = { @@ -4919,17 +4939,20 @@ autodiff_expression_handler: type = { { if primary.is_identifier() { primal_expr = primary.to_string(); - fwd_expr = add_suffix_if_not_wildcard(primal_expr); + fwd_expr = add_suffix_if_not_wildcard(primal_expr, ctx*.fwd_suffix); + rws_expr = add_suffix_if_not_wildcard(primal_expr, ctx*.rws_suffix); decl := ctx*.lookup_variable_declaration(primal_expr); if decl.is_member { fwd_expr = "this(ctx*.fwd_suffix)$." + fwd_expr; + rws_expr = "this(ctx*.rws_suffix)$." + rws_expr; } } else if primary.is_expression_list() { if primary.as_expression_list().is_empty() { primal_expr = "()"; fwd_expr = "()"; + rws_expr = "()"; // TODO: Check for reverse } else { primary.error("AD: Do not know how to handle non empty expression list inside of primary_expression: (primary.to_string())$"); @@ -4938,6 +4961,7 @@ autodiff_expression_handler: type = { else if primary.is_literal() { primal_expr = primary.to_string(); fwd_expr = "()"; + rws_expr = "()"; // TODO: Check for reverse } else if primary.is_declaration() { primary.error("AD: Do not know how to handle declaration inside of primary_expression: (primary.to_string())$"); @@ -5114,7 +5138,7 @@ autodiff_stmt_handler: type = { h: autodiff_expression_handler = (ctx); h.pre_traverse(assignment_terms[1].get_term()); - h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr); + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); append(h); } @@ -5234,7 +5258,7 @@ autodiff_declaration_handler: type = { ctx*.enter_function(); diff.add_forward(" (f.name())$(ctx*.fwd_suffix)$: ("); - diff.add_reverse(" (f.name())$(ctx*.rws_suffix)$: ("); + diff.add_reverse_primal(" (f.name())$(ctx*.rws_suffix)$: ("); // 1. Generate the modified signature // a) Parameters @@ -5252,22 +5276,22 @@ autodiff_declaration_handler: type = { diff.add_forward("(fwd_pass_style)$ (name)$, "); diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "); - diff.add_reverse("(fwd_pass_style)$ (name)$, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$, "); if ctx*.is_taylor() { // Add forward type for higher order - diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$: (fwd_ad_type)$, "); } - diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$: (rws_ad_type)$, "); + diff.add_reverse_primal("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$: (rws_ad_type)$, "); } else { type := param.get_declaration().type(); diff.add_forward("(fwd_pass_style)$ (name)$ : (type)$, "); diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); - diff.add_reverse("(fwd_pass_style)$ (name)$ : (type)$, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$ : (type)$, "); if ctx*.is_taylor() { - diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); } - diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$, "); + diff.add_reverse_primal("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$, "); ctx*.add_variable_declaration(name, type); @@ -5280,10 +5304,10 @@ autodiff_declaration_handler: type = { // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if f.has_deduced_return_type() { // TODO: Take care of initialization order error. - diff.add_reverse("inout r(ctx*.rws_suffix)$, "); + diff.add_reverse_primal("inout r(ctx*.rws_suffix)$, "); } else { - diff.add_reverse("inout r(ctx*.rws_suffix)$: (ctx*.get_rws_ad_type(f.get_unnamed_return_type()))$, "); + diff.add_reverse_primal("inout r(ctx*.rws_suffix)$: (ctx*.get_rws_ad_type(f.get_unnamed_return_type()))$, "); } } else { @@ -5292,12 +5316,12 @@ autodiff_declaration_handler: type = { type := param.get_declaration().type(); rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); - diff.add_reverse("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$ , "); + diff.add_reverse_primal("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$ , "); } } diff.add_forward(") -> ("); - diff.add_reverse(") -> ("); + diff.add_reverse_primal(") -> ("); // c) Returns @@ -5306,16 +5330,16 @@ autodiff_declaration_handler: type = { if f.has_deduced_return_type() { // TODO: Take care of initialization order error. diff.add_forward("r, r(ctx*.fwd_suffix)$, "); - diff.add_reverse("r, "); + diff.add_reverse_primal("r, "); if ctx*.is_taylor() { - diff.add_reverse("r(ctx*.fwd_suffix)$,"); + diff.add_reverse_primal("r(ctx*.fwd_suffix)$,"); } } else { diff.add_forward("r: (f.get_unnamed_return_type())$ = (), r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "); - diff.add_reverse("r: (f.get_unnamed_return_type())$ = (), "); + diff.add_reverse_primal("r: (f.get_unnamed_return_type())$ = (), "); if ctx*.is_taylor() { - diff.add_reverse("r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "); + diff.add_reverse_primal("r(ctx*.fwd_suffix)$: (ctx*.get_fwd_ad_type(f.get_unnamed_return_type()))$ = (), "); } } } @@ -5329,9 +5353,9 @@ autodiff_declaration_handler: type = { diff.add_forward("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); - diff.add_reverse("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); if ctx*.is_taylor() { - diff.add_reverse("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); } ctx*.add_variable_declaration("(name)$", "(type)$"); @@ -5339,7 +5363,7 @@ autodiff_declaration_handler: type = { } diff.add_forward(") = {"); - diff.add_reverse(") = {"); + diff.add_reverse_primal(") = {"); // Generate the body @@ -5357,10 +5381,11 @@ autodiff_declaration_handler: type = { ad_impl..pre_traverse(stmt); } diff.add_forward(ad_impl.diff.fwd); - diff.add_reverse(ad_impl.diff.rws); + diff.add_reverse_primal(ad_impl.diff.rws_primal); + diff.add_reverse_primal(ad_impl.diff.rws_backprop); diff.add_forward("}"); - diff.add_reverse("}"); + diff.add_reverse_primal("}"); ctx*.leave_function(); @@ -5368,7 +5393,7 @@ autodiff_declaration_handler: type = { decl.add_member( diff.fwd ); } if ctx*.is_reverse() { - decl.add_member( diff.rws ); + decl.add_member( diff.rws_primal ); } diff.reset(); From c5258a230e0545b427988d29f499d9f9aa3a75cf Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 26 Aug 2025 23:07:47 +0200 Subject: [PATCH 42/54] Basic handling of multiplication and division. --- include/cpp2taylor.h | 164 ++--- include/cpp2taylor.h2 | 14 +- source/reflect.h | 1363 +++++++++++++++++++++-------------------- source/reflect.h2 | 53 +- 4 files changed, 855 insertions(+), 739 deletions(-) diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index 1b85a3d1f..636805d3f 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -16,7 +16,7 @@ namespace cpp2 { template class taylor; -#line 243 "cpp2taylor.h2" +#line 257 "cpp2taylor.h2" } @@ -30,7 +30,7 @@ template class taylor; namespace cpp2 { template class taylor { - private: std::array v {}; + public: std::array v {}; public: explicit taylor(); public: taylor(R const& d1); @@ -63,58 +63,66 @@ template class taylor { public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; -#line 57 "cpp2taylor.h2" +#line 58 "cpp2taylor.h2" + // Overload for reverse AD. + public: auto operator+=(cpp2::impl::in o) & -> auto&&; + +#line 64 "cpp2taylor.h2" + // Overload for reverse AD. + public: auto operator-=(cpp2::impl::in o) & -> auto&&; + +#line 70 "cpp2taylor.h2" // Overload for simple handling of connected adds. public: [[nodiscard]] auto operator+(cpp2::impl::in o) const& -> taylor; -#line 62 "cpp2taylor.h2" +#line 75 "cpp2taylor.h2" // Overload for simple handling of connected minuses. public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; -#line 67 "cpp2taylor.h2" +#line 80 "cpp2taylor.h2" // Overload for simple handling of prefix +. public: [[nodiscard]] auto operator+() const& -> taylor; -#line 72 "cpp2taylor.h2" +#line 85 "cpp2taylor.h2" // Overload for simple handling of prefix -. public: [[nodiscard]] auto operator-() const& -> taylor; -#line 84 "cpp2taylor.h2" +#line 97 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 95 "cpp2taylor.h2" +#line 108 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 106 "cpp2taylor.h2" - public: [[nodiscard]] auto mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; - #line 119 "cpp2taylor.h2" + public: template [[nodiscard]] auto mul(taylor const& o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; + +#line 133 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; -#line 137 "cpp2taylor.h2" +#line 151 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; -#line 156 "cpp2taylor.h2" +#line 170 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; -#line 175 "cpp2taylor.h2" +#line 189 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; -#line 194 "cpp2taylor.h2" +#line 208 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; -#line 211 "cpp2taylor.h2" +#line 225 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; -#line 221 "cpp2taylor.h2" +#line 235 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; -#line 230 "cpp2taylor.h2" +#line 244 "cpp2taylor.h2" }; template [[nodiscard]] auto to_string(taylor const& o) -> std::string; -#line 243 "cpp2taylor.h2" +#line 257 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H @@ -220,102 +228,116 @@ auto i{2}; #line 47 "cpp2taylor.h2" template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ - if (cpp2::cpp2_default.is_active() && !([_0 = 0, _1 = i, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } - if (i == 0) { return v0; } + else {if (cpp2::impl::cmp_greater(i,dim)) { + return 0.0; + }} return CPP2_ASSERT_IN_BOUNDS(v, i - 1); } -#line 58 "cpp2taylor.h2" +#line 59 "cpp2taylor.h2" + template auto taylor::operator+=(cpp2::impl::in o) & -> auto&&{ + (*this) = (*this) + o; + return (*this); + } + +#line 65 "cpp2taylor.h2" + template auto taylor::operator-=(cpp2::impl::in o) & -> auto&&{ + (*this) = (*this) - o; + return (*this); + } + +#line 71 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+(cpp2::impl::in o) const& -> taylor{ return add(o, 0.0, 0.0); // Primal values are not required. } -#line 63 "cpp2taylor.h2" +#line 76 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-(cpp2::impl::in o) const& -> taylor{ return sub(o, 0.0, 0.0); // Primal values are not required. } -#line 68 "cpp2taylor.h2" +#line 81 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+() const& -> taylor{ return (*this); } -#line 73 "cpp2taylor.h2" +#line 86 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-() const& -> taylor{ taylor r {}; { auto k{1}; -#line 77 "cpp2taylor.h2" +#line 90 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = -CPP2_ASSERT_IN_BOUNDS(v, k - 1); } } -#line 81 "cpp2taylor.h2" +#line 94 "cpp2taylor.h2" return r; } -#line 84 "cpp2taylor.h2" +#line 97 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 88 "cpp2taylor.h2" +#line 101 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } -#line 92 "cpp2taylor.h2" +#line 105 "cpp2taylor.h2" return r; } -#line 95 "cpp2taylor.h2" +#line 108 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; -#line 99 "cpp2taylor.h2" +#line 112 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } -#line 103 "cpp2taylor.h2" +#line 116 "cpp2taylor.h2" return r; } -#line 106 "cpp2taylor.h2" - template [[nodiscard]] auto taylor::mul(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ - taylor r {}; +#line 119 "cpp2taylor.h2" + template template [[nodiscard]] auto taylor::mul(taylor const& o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ + int constexpr dim_r{ std::max(dim, dim_o) }; + taylor r {}; { auto k{1}; -#line 110 "cpp2taylor.h2" - for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { +#line 124 "cpp2taylor.h2" + for( ; cpp2::impl::cmp_less_eq(k,dim_r); k += 1 ) { { auto j{0}; -#line 112 "cpp2taylor.h2" +#line 126 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } -#line 115 "cpp2taylor.h2" +#line 129 "cpp2taylor.h2" } } -#line 116 "cpp2taylor.h2" +#line 130 "cpp2taylor.h2" return r; } -#line 119 "cpp2taylor.h2" +#line 133 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; @@ -324,26 +346,26 @@ auto j{0}; { auto k{1}; -#line 126 "cpp2taylor.h2" +#line 140 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; -#line 129 "cpp2taylor.h2" +#line 143 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } -#line 132 "cpp2taylor.h2" +#line 146 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 134 "cpp2taylor.h2" +#line 148 "cpp2taylor.h2" return r; } -#line 137 "cpp2taylor.h2" +#line 151 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; @@ -352,27 +374,27 @@ auto j{0}; { auto k{1}; -#line 144 "cpp2taylor.h2" +#line 158 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; -#line 147 "cpp2taylor.h2" +#line 161 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } -#line 150 "cpp2taylor.h2" +#line 164 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } -#line 153 "cpp2taylor.h2" +#line 167 "cpp2taylor.h2" return r; } -#line 156 "cpp2taylor.h2" +#line 170 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; @@ -381,27 +403,27 @@ auto j{1}; { auto k{1}; -#line 163 "cpp2taylor.h2" +#line 177 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; -#line 166 "cpp2taylor.h2" +#line 180 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } -#line 169 "cpp2taylor.h2" +#line 183 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } -#line 172 "cpp2taylor.h2" +#line 186 "cpp2taylor.h2" return r; } -#line 175 "cpp2taylor.h2" +#line 189 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; @@ -410,52 +432,52 @@ auto j{1}; { auto k{1}; -#line 182 "cpp2taylor.h2" +#line 196 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 184 "cpp2taylor.h2" +#line 198 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } -#line 187 "cpp2taylor.h2" +#line 201 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } -#line 190 "cpp2taylor.h2" +#line 204 "cpp2taylor.h2" return r; } -#line 194 "cpp2taylor.h2" +#line 208 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; -#line 199 "cpp2taylor.h2" +#line 213 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; -#line 201 "cpp2taylor.h2" +#line 215 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); } } -#line 205 "cpp2taylor.h2" +#line 219 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } -#line 208 "cpp2taylor.h2" +#line 222 "cpp2taylor.h2" } -#line 211 "cpp2taylor.h2" +#line 225 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -466,7 +488,7 @@ auto j{1}; return r; } -#line 221 "cpp2taylor.h2" +#line 235 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; @@ -477,18 +499,18 @@ auto j{1}; return r; } -#line 232 "cpp2taylor.h2" +#line 246 "cpp2taylor.h2" template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ std::string r {"("}; { auto i{1}; -#line 235 "cpp2taylor.h2" +#line 249 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; } } -#line 238 "cpp2taylor.h2" +#line 252 "cpp2taylor.h2" r += " )"; return r; diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index eb1654fa5..95f4eb813 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -4,7 +4,7 @@ cpp2: namespace = { taylor: type = { - v : std::array = (); + public v : std::array = (); operator=:(out this) = {} operator=:(out this, d1: R) = { @@ -45,11 +45,12 @@ taylor: type = { // C++2 interface / AD interface get: (this, i: int, v0: R) -> R = { - assert(0 <= i <= dim); - if i == 0 { return v0; } + else if i > dim { + return 0.0; + } return v[i - 1]; } @@ -115,11 +116,12 @@ taylor: type = { return r; } - mul: (this, o: taylor, v0: R, o0: R) -> taylor = { - r: taylor = (); + mul: (this, in_ref o: taylor, v0: R, o0: R) -> taylor = { + dim_r : int == std::max(dim, dim_o); + r: taylor = (); (copy k:= 1) - while k <= dim next k += 1 { + while k <= dim_r next k += 1 { (copy j := 0) while j <= k next j += 1 { r..v[k - 1] += get(j, v0) * o..get(k - j, o0); diff --git a/source/reflect.h b/source/reflect.h index aae474c41..bc4e4cfc3 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -125,91 +125,91 @@ class autodiff_context; class autodiff_diff_code; -#line 4428 "reflect.h2" +#line 4431 "reflect.h2" class autodiff_handler_base; -#line 4444 "reflect.h2" +#line 4449 "reflect.h2" class autodiff_expression_handler; -#line 4951 "reflect.h2" +#line 5004 "reflect.h2" class autodiff_stmt_handler; -#line 5212 "reflect.h2" +#line 5265 "reflect.h2" class autodiff_declaration_handler; -#line 5545 "reflect.h2" +#line 5599 "reflect.h2" class expression_flags; -#line 5561 "reflect.h2" +#line 5615 "reflect.h2" class regex_token; -#line 5588 "reflect.h2" +#line 5642 "reflect.h2" class regex_token_check; -#line 5609 "reflect.h2" +#line 5663 "reflect.h2" class regex_token_code; -#line 5630 "reflect.h2" +#line 5684 "reflect.h2" class regex_token_empty; -#line 5648 "reflect.h2" +#line 5702 "reflect.h2" class regex_token_list; -#line 5700 "reflect.h2" +#line 5754 "reflect.h2" class parse_context_group_state; -#line 5761 "reflect.h2" +#line 5815 "reflect.h2" class parse_context_branch_reset_state; -#line 5804 "reflect.h2" +#line 5858 "reflect.h2" class parse_context; -#line 6205 "reflect.h2" +#line 6259 "reflect.h2" class generation_function_context; -#line 6223 "reflect.h2" +#line 6277 "reflect.h2" class generation_context; -#line 6422 "reflect.h2" +#line 6476 "reflect.h2" class alternative_token; -#line 6437 "reflect.h2" +#line 6491 "reflect.h2" class alternative_token_gen; -#line 6502 "reflect.h2" +#line 6556 "reflect.h2" class any_token; -#line 6519 "reflect.h2" +#line 6573 "reflect.h2" class atomic_group_token; -#line 6549 "reflect.h2" +#line 6603 "reflect.h2" class char_token; -#line 6664 "reflect.h2" +#line 6718 "reflect.h2" class class_token; -#line 6888 "reflect.h2" +#line 6942 "reflect.h2" class group_ref_token; -#line 7025 "reflect.h2" +#line 7079 "reflect.h2" class group_token; -#line 7372 "reflect.h2" +#line 7426 "reflect.h2" class lookahead_lookbehind_token; -#line 7467 "reflect.h2" +#line 7521 "reflect.h2" class range_token; -#line 7624 "reflect.h2" +#line 7678 "reflect.h2" class special_range_token; -#line 7710 "reflect.h2" +#line 7764 "reflect.h2" template class regex_generator; -#line 7967 "reflect.h2" +#line 8021 "reflect.h2" } } @@ -1857,265 +1857,272 @@ struct lookup_special_function_handling_ret { bool m; std::string code_primal; s class autodiff_diff_code { public: autodiff_context* ctx; - public: std::string fwd {""}; - public: std::string rws {""}; + public: std::string fwd {""}; + public: std::string rws_primal {""}; + public: std::string rws_backprop {""}; public: autodiff_diff_code(autodiff_context* ctx_); -#line 4389 "reflect.h2" +#line 4390 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_diff_code& ; -#line 4393 "reflect.h2" +#line 4394 "reflect.h2" public: auto add_forward(cpp2::impl::in v) & -> void; - public: auto add_reverse(cpp2::impl::in v) & -> void; + public: auto add_reverse_primal(cpp2::impl::in v) & -> void; + public: auto add_reverse_backprop(cpp2::impl::in v) & -> void; public: auto reset() & -> void; -#line 4402 "reflect.h2" +#line 4405 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4408 "reflect.h2" +#line 4411 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4413 "reflect.h2" +#line 4416 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4418 "reflect.h2" +#line 4421 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_diff_code const&) -> void = delete; -#line 4421 "reflect.h2" +#line 4424 "reflect.h2" }; -#line 4428 "reflect.h2" +#line 4431 "reflect.h2" class autodiff_handler_base { public: autodiff_context* ctx; public: autodiff_diff_code diff; public: autodiff_handler_base(autodiff_context* ctx_); -#line 4433 "reflect.h2" +#line 4436 "reflect.h2" public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; -#line 4439 "reflect.h2" +#line 4442 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4442 "reflect.h2" +#line 4447 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4448 "reflect.h2" +#line 4453 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; public: std::string fwd_expr {""}; + public: std::string rws_expr {""}; public: autodiff_expression_handler(autodiff_context* ctx_); -#line 4457 "reflect.h2" - public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string; +#line 4463 "reflect.h2" + public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; + +#line 4472 "reflect.h2" + public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; -#line 4466 "reflect.h2" - public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void; +#line 4481 "reflect.h2" + public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4470 "reflect.h2" - public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto); +#line 4491 "reflect.h2" + public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4476 "reflect.h2" - public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void; +#line 4497 "reflect.h2" + public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4480 "reflect.h2" - public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto); +#line 4507 "reflect.h2" + public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); - public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto); + public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4489 "reflect.h2" - public: class primal_fwd_name { +#line 4516 "reflect.h2" + public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; - public: primal_fwd_name(auto&& primal_, auto&& fwd_) -CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&>) ; -public: primal_fwd_name(); + public: std::string rws {""}; + public: primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_) +CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; +public: primal_fwd_rws_name(); -#line 4492 "reflect.h2" +#line 4520 "reflect.h2" }; - public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; + public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4503 "reflect.h2" - public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_name; +#line 4531 "reflect.h2" + public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4554 "reflect.h2" +#line 4584 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4698 "reflect.h2" - public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; +#line 4728 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4733 "reflect.h2" +#line 4763 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4737 "reflect.h2" +#line 4767 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4741 "reflect.h2" +#line 4771 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4745 "reflect.h2" +#line 4775 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4749 "reflect.h2" +#line 4779 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4753 "reflect.h2" +#line 4783 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4757 "reflect.h2" +#line 4787 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4761 "reflect.h2" +#line 4791 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4765 "reflect.h2" +#line 4795 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4769 "reflect.h2" +#line 4799 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4773 "reflect.h2" +#line 4803 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4777 "reflect.h2" +#line 4807 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4801 "reflect.h2" +#line 4836 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4858 "reflect.h2" +#line 4907 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 4862 "reflect.h2" +#line 4911 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 4878 "reflect.h2" +#line 4927 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 4918 "reflect.h2" +#line 4967 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 4949 "reflect.h2" +#line 5002 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 4955 "reflect.h2" +#line 5008 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); -#line 4964 "reflect.h2" +#line 5017 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 4969 "reflect.h2" +#line 5022 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 4974 "reflect.h2" +#line 5027 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5003 "reflect.h2" +#line 5056 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5008 "reflect.h2" +#line 5061 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5013 "reflect.h2" +#line 5066 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5018 "reflect.h2" +#line 5071 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5026 "reflect.h2" +#line 5079 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5043 "reflect.h2" +#line 5096 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5093 "reflect.h2" +#line 5146 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5104 "reflect.h2" +#line 5157 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5108 "reflect.h2" +#line 5161 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5121 "reflect.h2" +#line 5174 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5125 "reflect.h2" +#line 5178 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5129 "reflect.h2" +#line 5182 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5133 "reflect.h2" +#line 5186 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5137 "reflect.h2" +#line 5190 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5141 "reflect.h2" +#line 5194 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5145 "reflect.h2" +#line 5198 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5149 "reflect.h2" +#line 5202 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5153 "reflect.h2" +#line 5206 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5157 "reflect.h2" +#line 5210 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5161 "reflect.h2" +#line 5214 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5165 "reflect.h2" +#line 5218 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5169 "reflect.h2" +#line 5222 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5174 "reflect.h2" +#line 5227 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5206 "reflect.h2" +#line 5259 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5210 "reflect.h2" +#line 5263 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5216 "reflect.h2" +#line 5269 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2125,37 +2132,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); -#line 5228 "reflect.h2" +#line 5281 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5233 "reflect.h2" +#line 5286 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5379 "reflect.h2" +#line 5433 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5407 "reflect.h2" +#line 5461 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5431 "reflect.h2" +#line 5485 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5436 "reflect.h2" +#line 5490 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5439 "reflect.h2" +#line 5493 "reflect.h2" }; -#line 5442 "reflect.h2" +#line 5496 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5541 "reflect.h2" +#line 5595 "reflect.h2" using error_func = std::function x)>; -#line 5545 "reflect.h2" +#line 5599 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2190,20 +2197,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5553 "reflect.h2" +#line 5607 "reflect.h2" }; -#line 5561 "reflect.h2" +#line 5615 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5569 "reflect.h2" +#line 5623 "reflect.h2" public: explicit regex_token(); -#line 5574 "reflect.h2" +#line 5628 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2215,103 +2222,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5580 "reflect.h2" +#line 5634 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5586 "reflect.h2" +#line 5640 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5592 "reflect.h2" +#line 5646 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5599 "reflect.h2" +#line 5653 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5603 "reflect.h2" +#line 5657 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5604 "reflect.h2" +#line 5658 "reflect.h2" }; -#line 5607 "reflect.h2" +#line 5661 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5613 "reflect.h2" +#line 5667 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5620 "reflect.h2" +#line 5674 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5624 "reflect.h2" +#line 5678 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5625 "reflect.h2" +#line 5679 "reflect.h2" }; -#line 5628 "reflect.h2" +#line 5682 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5634 "reflect.h2" +#line 5688 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5638 "reflect.h2" +#line 5692 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5642 "reflect.h2" +#line 5696 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5643 "reflect.h2" +#line 5697 "reflect.h2" }; -#line 5646 "reflect.h2" +#line 5700 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5652 "reflect.h2" +#line 5706 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5659 "reflect.h2" +#line 5713 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5665 "reflect.h2" +#line 5719 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5671 "reflect.h2" +#line 5725 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5679 "reflect.h2" +#line 5733 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2319,10 +2326,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5691 "reflect.h2" +#line 5745 "reflect.h2" }; -#line 5694 "reflect.h2" +#line 5748 "reflect.h2" // // Parse and generation context. // @@ -2338,33 +2345,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5714 "reflect.h2" +#line 5768 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5721 "reflect.h2" +#line 5775 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5733 "reflect.h2" +#line 5787 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5738 "reflect.h2" +#line 5792 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5742 "reflect.h2" +#line 5796 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5756 "reflect.h2" +#line 5810 "reflect.h2" }; -#line 5759 "reflect.h2" +#line 5813 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2377,25 +2384,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5777 "reflect.h2" +#line 5831 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5783 "reflect.h2" +#line 5837 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5790 "reflect.h2" +#line 5844 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5797 "reflect.h2" +#line 5851 "reflect.h2" }; -#line 5800 "reflect.h2" +#line 5854 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2411,7 +2418,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 5816 "reflect.h2" +#line 5870 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2419,64 +2426,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 5827 "reflect.h2" +#line 5881 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 5840 "reflect.h2" +#line 5894 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 5848 "reflect.h2" +#line 5902 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 5852 "reflect.h2" +#line 5906 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 5856 "reflect.h2" +#line 5910 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 5868 "reflect.h2" +#line 5922 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 5875 "reflect.h2" +#line 5929 "reflect.h2" public: auto next_alternative() & -> void; -#line 5881 "reflect.h2" +#line 5935 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 5887 "reflect.h2" +#line 5941 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 5891 "reflect.h2" +#line 5945 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 5902 "reflect.h2" +#line 5956 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5906 "reflect.h2" +#line 5960 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 5912 "reflect.h2" +#line 5966 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 5916 "reflect.h2" +#line 5970 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 5923 "reflect.h2" +#line 5977 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 5934 "reflect.h2" +#line 5988 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2484,51 +2491,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 5978 "reflect.h2" +#line 6032 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 5990 "reflect.h2" +#line 6044 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6003 "reflect.h2" +#line 6057 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6026 "reflect.h2" +#line 6080 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6043 "reflect.h2" +#line 6097 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6064 "reflect.h2" +#line 6118 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6074 "reflect.h2" +#line 6128 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6078 "reflect.h2" +#line 6132 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6134 "reflect.h2" +#line 6188 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6173 "reflect.h2" +#line 6227 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6188 "reflect.h2" +#line 6242 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2540,10 +2547,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6199 "reflect.h2" +#line 6253 "reflect.h2" }; -#line 6202 "reflect.h2" +#line 6256 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2553,16 +2560,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6216 "reflect.h2" +#line 6270 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6219 "reflect.h2" +#line 6273 "reflect.h2" }; -#line 6222 "reflect.h2" +#line 6276 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2582,68 +2589,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6244 "reflect.h2" +#line 6298 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6250 "reflect.h2" +#line 6304 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6259 "reflect.h2" +#line 6313 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6270 "reflect.h2" +#line 6324 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6277 "reflect.h2" +#line 6331 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6297 "reflect.h2" +#line 6351 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6307 "reflect.h2" +#line 6361 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6330 "reflect.h2" +#line 6384 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6338 "reflect.h2" +#line 6392 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6342 "reflect.h2" +#line 6396 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6348 "reflect.h2" +#line 6402 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6354 "reflect.h2" +#line 6408 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6364 "reflect.h2" +#line 6418 "reflect.h2" public: auto finish_context() & -> void; -#line 6372 "reflect.h2" +#line 6426 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6378 "reflect.h2" +#line 6432 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6382 "reflect.h2" +#line 6436 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6386 "reflect.h2" +#line 6440 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6410 "reflect.h2" +#line 6464 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2651,7 +2658,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6416 "reflect.h2" +#line 6470 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2671,27 +2678,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6435 "reflect.h2" +#line 6489 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6441 "reflect.h2" +#line 6495 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6448 "reflect.h2" +#line 6502 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6465 "reflect.h2" +#line 6519 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6472 "reflect.h2" +#line 6526 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6485 "reflect.h2" +#line 6539 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2699,19 +2706,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6497 "reflect.h2" +#line 6551 "reflect.h2" }; -#line 6500 "reflect.h2" +#line 6554 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6506 "reflect.h2" +#line 6560 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6510 "reflect.h2" +#line 6564 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2719,7 +2726,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6515 "reflect.h2" +#line 6569 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2727,17 +2734,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6523 "reflect.h2" +#line 6577 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6534 "reflect.h2" +#line 6588 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6542 "reflect.h2" +#line 6596 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2745,7 +2752,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6545 "reflect.h2" +#line 6599 "reflect.h2" }; // Regex syntax: a @@ -2753,34 +2760,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6553 "reflect.h2" +#line 6607 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6562 "reflect.h2" +#line 6616 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6568 "reflect.h2" +#line 6622 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6572 "reflect.h2" +#line 6626 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6595 "reflect.h2" +#line 6649 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6616 "reflect.h2" +#line 6670 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6634 "reflect.h2" +#line 6688 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6649 "reflect.h2" +#line 6703 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6655 "reflect.h2" +#line 6709 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2788,33 +2795,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6659 "reflect.h2" +#line 6713 "reflect.h2" }; -#line 6662 "reflect.h2" +#line 6716 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6668 "reflect.h2" +#line 6722 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6680 "reflect.h2" +#line 6734 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6806 "reflect.h2" +#line 6860 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6815 "reflect.h2" +#line 6869 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6820 "reflect.h2" +#line 6874 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2822,20 +2829,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 6827 "reflect.h2" +#line 6881 "reflect.h2" }; -#line 6830 "reflect.h2" +#line 6884 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 6871 "reflect.h2" +#line 6925 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 6882 "reflect.h2" +#line 6936 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2845,20 +2852,20 @@ class class_token class group_ref_token : public regex_token { -#line 6892 "reflect.h2" +#line 6946 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 6904 "reflect.h2" +#line 6958 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7005 "reflect.h2" +#line 7059 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7009 "reflect.h2" +#line 7063 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2866,10 +2873,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7012 "reflect.h2" +#line 7066 "reflect.h2" }; -#line 7015 "reflect.h2" +#line 7069 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2883,29 +2890,29 @@ class group_ref_token class group_token : public regex_token { -#line 7029 "reflect.h2" +#line 7083 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7051 "reflect.h2" +#line 7105 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7065 "reflect.h2" +#line 7119 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7224 "reflect.h2" +#line 7278 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7232 "reflect.h2" +#line 7286 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7250 "reflect.h2" +#line 7304 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7281 "reflect.h2" +#line 7335 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2914,25 +2921,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7288 "reflect.h2" +#line 7342 "reflect.h2" }; -#line 7291 "reflect.h2" +#line 7345 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7332 "reflect.h2" +#line 7386 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7352 "reflect.h2" +#line 7406 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7368 "reflect.h2" +#line 7422 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2940,20 +2947,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7376 "reflect.h2" +#line 7430 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7385 "reflect.h2" +#line 7439 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7396 "reflect.h2" +#line 7450 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7403 "reflect.h2" +#line 7457 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2961,26 +2968,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7406 "reflect.h2" +#line 7460 "reflect.h2" }; -#line 7409 "reflect.h2" +#line 7463 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7437 "reflect.h2" +#line 7491 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7465 "reflect.h2" +#line 7519 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7471 "reflect.h2" +#line 7525 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -2990,22 +2997,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7551 "reflect.h2" +#line 7605 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7563 "reflect.h2" +#line 7617 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7576 "reflect.h2" +#line 7630 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7595 "reflect.h2" +#line 7649 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7605 "reflect.h2" +#line 7659 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7616 "reflect.h2" +#line 7670 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3013,16 +3020,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7619 "reflect.h2" +#line 7673 "reflect.h2" }; -#line 7622 "reflect.h2" +#line 7676 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7628 "reflect.h2" +#line 7682 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3031,7 +3038,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7658 "reflect.h2" +#line 7712 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3040,14 +3047,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7680 "reflect.h2" +#line 7734 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7702 "reflect.h2" +#line 7756 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3068,24 +3075,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7725 "reflect.h2" +#line 7779 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7760 "reflect.h2" +#line 7814 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7774 "reflect.h2" +#line 7828 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7786 "reflect.h2" +#line 7840 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 7841 "reflect.h2" +#line 7895 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3096,7 +3103,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 7967 "reflect.h2" +#line 8021 "reflect.h2" } } @@ -8160,144 +8167,174 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4389 "reflect.h2" +#line 4390 "reflect.h2" autodiff_diff_code::autodiff_diff_code(autodiff_context* ctx_) : ctx{ ctx_ }{ -#line 4391 "reflect.h2" +#line 4392 "reflect.h2" } -#line 4389 "reflect.h2" +#line 4390 "reflect.h2" auto autodiff_diff_code::operator=(autodiff_context* ctx_) -> autodiff_diff_code& { ctx = ctx_; fwd = ""; - rws = ""; + rws_primal = ""; + rws_backprop = ""; return *this; -#line 4391 "reflect.h2" +#line 4392 "reflect.h2" } -#line 4393 "reflect.h2" - auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v; }} #line 4394 "reflect.h2" - auto autodiff_diff_code::add_reverse(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws += v; }} - + auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} +#line 4395 "reflect.h2" + auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} #line 4396 "reflect.h2" + auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop += v; }} + +#line 4398 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ - fwd = ""; - rws = ""; + fwd = ""; + rws_primal = ""; + rws_backprop = ""; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4402 "reflect.h2" +#line 4405 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; - rws = ""; + rws_primal = ""; + rws_backprop = ""; return *this; -#line 4405 "reflect.h2" +#line 4408 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4408 "reflect.h2" +#line 4411 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4413 "reflect.h2" +#line 4416 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4418 "reflect.h2" +#line 4421 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4423 "reflect.h2" +#line 4426 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4433 "reflect.h2" +#line 4436 "reflect.h2" autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4436 "reflect.h2" +#line 4439 "reflect.h2" } -#line 4433 "reflect.h2" +#line 4436 "reflect.h2" auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4436 "reflect.h2" +#line 4439 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4439 "reflect.h2" +#line 4442 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ - diff += o.diff.fwd; + diff.fwd += o.diff.fwd; + diff.rws_primal += o.diff.rws_primal; + diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4453 "reflect.h2" +#line 4459 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4455 "reflect.h2" +#line 4461 "reflect.h2" } -#line 4457 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs) const& -> std::string{ +#line 4463 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; } else { - return lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; + return lhs + suffix; } } -#line 4466 "reflect.h2" - auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d) & -> void{ - diff += "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; - diff += "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"; - } -#line 4470 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d) & -> decltype(auto) { - return gen_assignment(lhs, lhs_d, primal_expr, fwd_expr); } #line 4472 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { - return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs), primal_expr, fwd_expr); } - -#line 4476 "reflect.h2" - auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type, cpp2::impl::in type_d) & -> void{ - diff += "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"; - diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"; - } -#line 4480 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs_d, rhs, rhs_d, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4482 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4484 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { - return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, primal_expr, fwd_expr, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } + [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ + auto r {rhs_b}; + r = string_util::replace_all(r, "_r_", lhs); + r = string_util::replace_all(r, "_rd_", lhs_d); + r = string_util::replace_all(r, "_rb_", lhs_b); - autodiff_expression_handler::primal_fwd_name::primal_fwd_name(auto&& primal_, auto&& fwd_) -requires (std::is_convertible_v&> && std::is_convertible_v&>) - : primal{ CPP2_FORWARD(primal_) } - , fwd{ CPP2_FORWARD(fwd_) }{} -autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} + return r; + } -#line 4494 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ - std::vector args {}; +#line 4481 "reflect.h2" + auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); + + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); + } + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); + CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); + } +#line 4491 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { + return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } +#line 4493 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { + return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } + +#line 4497 "reflect.h2" + auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); + + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); + } + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); + CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); + } +#line 4507 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } +#line 4509 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } +#line 4511 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { + return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } + + autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_) +requires (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) + : primal{ CPP2_FORWARD(primal_) } + , fwd{ CPP2_FORWARD(fwd_) } + , rws{ CPP2_FORWARD(rws_) }{} +autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} + +#line 4522 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ + std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { CPP2_UFCS(push_back)(args, handle_expression_term(expr)); } @@ -8305,30 +8342,32 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} return args; } -#line 4503 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_name{ +#line 4531 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; auto fwd {primal + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; + auto rws {primal + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal)}; if (cpp2::move(decl).is_member) { fwd = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "." + fwd; + rws = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "." + rws; } - return { cpp2::move(primal), cpp2::move(fwd) }; + return { cpp2::move(primal), cpp2::move(fwd), cpp2::move(rws) }; } else {if (CPP2_UFCS(is_expression_list)(term)) { auto exprs {term.as_expression_list().get_expressions()}; if (CPP2_UFCS(ssize)(exprs) != 1) { CPP2_UFCS(error)(term, "Can not handle multiple expressions. (term.to_string())"); - return { "error", "" }; + return { "error", "", "" }; } auto expr {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(exprs), 0)}; auto bin_expr {expr.as_assignment_expression()}; if (CPP2_UFCS(terms_size)(bin_expr) != 0) { CPP2_UFCS(error)(term, "Can not handle assign expr inside of expression. " + cpp2::to_string(CPP2_UFCS(to_string)(cpp2::move(expr))) + ""); - return { "error", "" }; + return { "error", "", "" }; } autodiff_expression_handler ad {ctx}; @@ -8337,7 +8376,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + primal_fwd_rws_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) static_cast(cpp2::move(t)); return r; } @@ -8351,13 +8390,13 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression append(cpp2::move(ad)); - primal_fwd_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + primal_fwd_rws_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) static_cast(cpp2::move(t)); return r; }} } -#line 4554 "reflect.h2" +#line 4584 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8365,7 +8404,7 @@ autodiff_expression_handler::primal_fwd_name::primal_fwd_name(){} { auto i{0}; -#line 4560 "reflect.h2" +#line 4590 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8379,7 +8418,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4572 "reflect.h2" +#line 4602 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8388,7 +8427,7 @@ auto i{0}; std::string object {""}; std::string object_d {""}; std::string function_name {""}; - std::vector args {}; + std::vector args {}; auto primary {CPP2_UFCS(get_primary_expression)(postfix)}; @@ -8402,7 +8441,7 @@ auto i{0}; { auto i{0}; -#line 4593 "reflect.h2" +#line 4623 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8427,7 +8466,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4616 "reflect.h2" +#line 4646 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8510,8 +8549,8 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4698 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ +#line 4728 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8533,7 +8572,7 @@ auto i{0}; { auto i{1}; -#line 4719 "reflect.h2" +#line 4749 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8543,84 +8582,88 @@ auto i{1}; } } -#line 4727 "reflect.h2" +#line 4757 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4733 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4737 "reflect.h2" +#line 4767 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4741 "reflect.h2" +#line 4771 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4745 "reflect.h2" +#line 4775 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4749 "reflect.h2" +#line 4779 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4753 "reflect.h2" +#line 4783 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4757 "reflect.h2" +#line 4787 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4761 "reflect.h2" +#line 4791 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4765 "reflect.h2" +#line 4795 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4769 "reflect.h2" +#line 4799 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4773 "reflect.h2" +#line 4803 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4777 "reflect.h2" +#line 4807 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto first {true}; + std::string op {"+"}; std::string fwd {""}; + std::string rws {""}; std::string primal {""}; for ( auto const& term : cpp2::move(terms) ) { if (!(first)) { - auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term))}; + op = CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term)); fwd += " " + cpp2::to_string(op) + " "; - primal += " " + cpp2::to_string(cpp2::move(op)) + " "; + primal += " " + cpp2::to_string(op) + " "; + } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; fwd += var.fwd; + rws += "" + cpp2::to_string(var.rws) + " " + cpp2::to_string(op) + "= _rb_;\n"; primal += cpp2::move(var).primal; first = false; @@ -8628,42 +8671,54 @@ auto i{1}; primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); + rws_expr = cpp2::move(rws); } -#line 4801 "reflect.h2" +#line 4836 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto var {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; auto arg_a {var.primal}; auto arg_a_d {var.fwd}; + auto arg_a_b {var.rws}; int i {1}; for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(terms)); i += 1 ) { var = handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i))); auto arg_b {var.primal}; auto arg_b_d {var.fwd}; + auto arg_b_b {var.rws}; auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; std::string fwd {""}; + std::string rws {""}; std::string primal {""}; if ("*" == op) { if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - fwd = "" + cpp2::to_string(arg_a_d) + ".mul(" + cpp2::to_string(cpp2::move(arg_b_d)) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + fwd = "" + cpp2::to_string(arg_a_d) + "..mul(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " += " + cpp2::to_string(arg_a_d) + "..mul(_rb_, " + cpp2::to_string(arg_a) + ", _r_);\n" + "" + cpp2::to_string(arg_a_b) + " += " + cpp2::to_string(cpp2::move(arg_b_d)) + "..mul(_rb_, " + cpp2::to_string(arg_b) + ", _r_);"; } else { fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a_d) + ""; + rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " += " + cpp2::to_string(arg_a) + " * _rb_;\n" + "" + cpp2::to_string(arg_a_b) + " += " + cpp2::to_string(arg_b) + " * _rb_;"; } primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; } else {if ("/" == op) { if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - fwd = "" + cpp2::to_string(arg_a_d) + ".div(" + cpp2::to_string(cpp2::move(arg_b_d)) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + fwd = "" + cpp2::to_string(arg_a_d) + ".div(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; + rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " -= " + cpp2::to_string(arg_a_d) + ".mul(_rb_, " + cpp2::to_string(arg_a) + ", _r_).div(" + cpp2::to_string(arg_b_d) + ".mul(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_b) + ", " + cpp2::to_string(arg_b) + "), " + cpp2::to_string(arg_a) + " * _r_, " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ");\n" + "" + cpp2::to_string(arg_a_b) + " += _rb_.div(" + cpp2::to_string(arg_b_d) + ", _r_, " + cpp2::to_string(arg_b) + ");"; } else { - fwd = "" + cpp2::to_string(arg_a_d) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + fwd = "" + cpp2::to_string(arg_a_d) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; + rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " -= " + cpp2::to_string(arg_a) + " * _rb_ / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ");\n" + "" + cpp2::to_string(arg_a_b) + " += _rb_ / " + cpp2::to_string(arg_b) + ";"; } primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; } @@ -8671,29 +8726,32 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 4842 "reflect.h2" +#line 4888 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); + rws_expr = cpp2::move(rws); } else { // Temporary auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; - gen_declaration(t, t_d, cpp2::move(primal), cpp2::move(fwd), "", ""); + auto t_b {t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; + gen_declaration(t, t_d, t_b, cpp2::move(primal), cpp2::move(fwd), cpp2::move(rws), "", "", ""); arg_a = cpp2::move(t); arg_a_d = cpp2::move(t_d); + arg_a_b = cpp2::move(t_b); } } } -#line 4858 "reflect.h2" +#line 4907 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 4862 "reflect.h2" +#line 4911 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -8710,7 +8768,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 4878 "reflect.h2" +#line 4927 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8719,7 +8777,7 @@ auto i{1}; { auto i{0}; -#line 4885 "reflect.h2" +#line 4934 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8734,7 +8792,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4898 "reflect.h2" +#line 4947 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8755,22 +8813,25 @@ auto i{0}; } } -#line 4918 "reflect.h2" +#line 4967 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { primal_expr = CPP2_UFCS(to_string)(primary); - fwd_expr = add_suffix_if_not_wildcard(primal_expr); + fwd_expr = add_suffix_if_not_wildcard(primal_expr, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix); + rws_expr = add_suffix_if_not_wildcard(primal_expr, (*cpp2::impl::assert_not_null(ctx)).rws_suffix); auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal_expr)}; if (cpp2::move(decl).is_member) { fwd_expr = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "." + fwd_expr; + rws_expr = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "." + rws_expr; } } else {if (CPP2_UFCS(is_expression_list)(primary)) { if (CPP2_UFCS(is_empty)(CPP2_UFCS(as_expression_list)(primary))) { primal_expr = "()"; fwd_expr = "()"; + rws_expr = "()"; // TODO: Check for reverse } else { CPP2_UFCS(error)(primary, "AD: Do not know how to handle non empty expression list inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -8779,6 +8840,7 @@ auto i{0}; else {if (CPP2_UFCS(is_literal)(primary)) { primal_expr = CPP2_UFCS(to_string)(primary); fwd_expr = "()"; + rws_expr = "()"; // TODO: Check for reverse } else {if (CPP2_UFCS(is_declaration)(primary)) { CPP2_UFCS(error)(primary, "AD: Do not know how to handle declaration inside of primary_expression: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); @@ -8788,26 +8850,26 @@ auto i{0}; }}}} } -#line 4959 "reflect.h2" +#line 5012 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 4962 "reflect.h2" +#line 5015 "reflect.h2" } -#line 4964 "reflect.h2" +#line 5017 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 4969 "reflect.h2" +#line 5022 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 4974 "reflect.h2" +#line 5027 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -8836,22 +8898,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); } -#line 5003 "reflect.h2" +#line 5056 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5008 "reflect.h2" +#line 5061 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5013 "reflect.h2" +#line 5066 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5018 "reflect.h2" +#line 5071 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -8859,7 +8921,7 @@ auto i{0}; diff += "}\n"; } -#line 5026 "reflect.h2" +#line 5079 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -8876,7 +8938,7 @@ auto i{0}; } } -#line 5043 "reflect.h2" +#line 5096 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -8926,7 +8988,7 @@ auto i{0}; }} } -#line 5093 "reflect.h2" +#line 5146 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -8938,12 +9000,12 @@ auto i{0}; } } -#line 5104 "reflect.h2" +#line 5157 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5108 "reflect.h2" +#line 5161 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -8953,77 +9015,77 @@ auto i{0}; autodiff_expression_handler h {ctx}; CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, cpp2::move(h_lhs).fwd_expr); + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, cpp2::move(h_lhs).rws_expr); append(cpp2::move(h)); } -#line 5121 "reflect.h2" +#line 5174 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5125 "reflect.h2" +#line 5178 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5129 "reflect.h2" +#line 5182 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5133 "reflect.h2" +#line 5186 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5137 "reflect.h2" +#line 5190 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5141 "reflect.h2" +#line 5194 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5145 "reflect.h2" +#line 5198 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5149 "reflect.h2" +#line 5202 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5153 "reflect.h2" +#line 5206 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5157 "reflect.h2" +#line 5210 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5161 "reflect.h2" +#line 5214 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5165 "reflect.h2" +#line 5218 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5169 "reflect.h2" +#line 5222 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5174 "reflect.h2" +#line 5227 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9032,7 +9094,7 @@ auto i{0}; { auto i{0}; -#line 5181 "reflect.h2" +#line 5234 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9047,7 +9109,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5194 "reflect.h2" +#line 5247 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9060,32 +9122,32 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5206 "reflect.h2" +#line 5259 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5223 "reflect.h2" +#line 5276 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5226 "reflect.h2" +#line 5279 "reflect.h2" } -#line 5228 "reflect.h2" +#line 5281 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5233 "reflect.h2" +#line 5286 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); CPP2_UFCS(add_forward)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": ("); - CPP2_UFCS(add_reverse)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": ("); + CPP2_UFCS(add_reverse_primal)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": ("); // 1. Generate the modified signature // a) Parameters @@ -9103,24 +9165,24 @@ auto i{0}; CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + ", "); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(fwd_ad_type) + ", "); - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + ", "); if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) {// Add forward type for higher order - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(cpp2::move(fwd_ad_type)) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(cpp2::move(fwd_ad_type)) + ", "); } - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(cpp2::move(rws_ad_type)) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(cpp2::move(rws_ad_type)) + ", "); } else { auto type {CPP2_UFCS(get_declaration)(param).type()}; CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); } - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); -#line 5273 "reflect.h2" +#line 5326 "reflect.h2" CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type)); } } @@ -9131,10 +9193,10 @@ auto i{0}; // TODO: check if name "r" is available. (Also needs inspection of functions at call sides.) if (CPP2_UFCS(has_deduced_return_type)(f)) { // TODO: Take care of initialization order error. - CPP2_UFCS(add_reverse)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ", "); } else { - CPP2_UFCS(add_reverse)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "inout r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + ", "); } } else { @@ -9143,12 +9205,12 @@ auto i{0}; auto type {CPP2_UFCS(get_declaration)(param).type()}; auto rws_pass_style {to_string_view(CPP2_UFCS(get_reverse_passing_style)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_passing_style)(param)))}; - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type))) + " , "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(cpp2::move(name)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type))) + " , "); } } CPP2_UFCS(add_forward)(diff, ") -> ("); - CPP2_UFCS(add_reverse)(diff, ") -> ("); + CPP2_UFCS(add_reverse_primal)(diff, ") -> ("); // c) Returns @@ -9157,16 +9219,16 @@ auto i{0}; if (CPP2_UFCS(has_deduced_return_type)(f)) { // TODO: Take care of initialization order error. CPP2_UFCS(add_forward)(diff, "r, r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ", "); - CPP2_UFCS(add_reverse)(diff, "r, "); + CPP2_UFCS(add_reverse_primal)(diff, "r, "); if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_reverse)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ","); + CPP2_UFCS(add_reverse_primal)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ","); } } else { CPP2_UFCS(add_forward)(diff, "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "); - CPP2_UFCS(add_reverse)(diff, "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), "); + CPP2_UFCS(add_reverse_primal)(diff, "r: " + cpp2::to_string(CPP2_UFCS(get_unnamed_return_type)(f)) + " = (), "); if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_reverse)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "); + CPP2_UFCS(add_reverse_primal)(diff, "r" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_unnamed_return_type)(f))) + " = (), "); } } } @@ -9180,9 +9242,9 @@ auto i{0}; CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_reverse)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); } CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + ""); @@ -9190,7 +9252,7 @@ auto i{0}; } CPP2_UFCS(add_forward)(diff, ") = {"); - CPP2_UFCS(add_reverse)(diff, ") = {"); + CPP2_UFCS(add_reverse_primal)(diff, ") = {"); // Generate the body @@ -9199,19 +9261,20 @@ auto i{0}; return ; } -#line 5352 "reflect.h2" +#line 5405 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5355 "reflect.h2" +#line 5408 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); } CPP2_UFCS(add_forward)(diff, ad_impl.diff.fwd); - CPP2_UFCS(add_reverse)(diff, cpp2::move(ad_impl).diff.rws); + CPP2_UFCS(add_reverse_primal)(diff, ad_impl.diff.rws_primal); + CPP2_UFCS(add_reverse_primal)(diff, cpp2::move(ad_impl).diff.rws_backprop); CPP2_UFCS(add_forward)(diff, "}"); - CPP2_UFCS(add_reverse)(diff, "}"); + CPP2_UFCS(add_reverse_primal)(diff, "}"); CPP2_UFCS(leave_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9219,14 +9282,14 @@ auto i{0}; CPP2_UFCS(add_member)(decl, diff.fwd); } if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_member)(decl, diff.rws); + CPP2_UFCS(add_member)(decl, diff.rws_primal); } CPP2_UFCS(reset)(diff); CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5379 "reflect.h2" +#line 5433 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9254,7 +9317,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); } -#line 5407 "reflect.h2" +#line 5461 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9278,17 +9341,17 @@ auto i{0}; } } -#line 5431 "reflect.h2" +#line 5485 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5436 "reflect.h2" +#line 5490 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5442 "reflect.h2" +#line 5496 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9464,7 +9527,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5527 "reflect.h2" +#line 5581 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9480,11 +9543,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5543 "reflect.h2" +#line 5597 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5547 "reflect.h2" +#line 5601 "reflect.h2" // mod: i // mod: m // mod: s @@ -9492,116 +9555,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5556 "reflect.h2" +#line 5610 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5565 "reflect.h2" +#line 5619 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5567 "reflect.h2" +#line 5621 "reflect.h2" } -#line 5569 "reflect.h2" +#line 5623 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5571 "reflect.h2" +#line 5625 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5577 "reflect.h2" +#line 5631 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5578 "reflect.h2" +#line 5632 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5579 "reflect.h2" +#line 5633 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5594 "reflect.h2" +#line 5648 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5597 "reflect.h2" +#line 5651 "reflect.h2" } -#line 5599 "reflect.h2" +#line 5653 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5603 "reflect.h2" +#line 5657 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5615 "reflect.h2" +#line 5669 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5618 "reflect.h2" +#line 5672 "reflect.h2" } -#line 5620 "reflect.h2" +#line 5674 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5624 "reflect.h2" +#line 5678 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5634 "reflect.h2" +#line 5688 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5636 "reflect.h2" +#line 5690 "reflect.h2" } -#line 5638 "reflect.h2" +#line 5692 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5642 "reflect.h2" +#line 5696 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5654 "reflect.h2" +#line 5708 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5657 "reflect.h2" +#line 5711 "reflect.h2" } -#line 5659 "reflect.h2" +#line 5713 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5665 "reflect.h2" +#line 5719 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5671 "reflect.h2" +#line 5725 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9610,7 +9673,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5679 "reflect.h2" +#line 5733 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9626,7 +9689,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5707 "reflect.h2" +#line 5761 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9634,14 +9697,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5715 "reflect.h2" +#line 5769 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5722 "reflect.h2" +#line 5776 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9653,15 +9716,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5734 "reflect.h2" +#line 5788 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5739 "reflect.h2" +#line 5793 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5743 "reflect.h2" +#line 5797 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9682,7 +9745,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5769 "reflect.h2" +#line 5823 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9691,20 +9754,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5778 "reflect.h2" +#line 5832 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5784 "reflect.h2" +#line 5838 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5791 "reflect.h2" +#line 5845 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9719,16 +9782,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 5821 "reflect.h2" +#line 5875 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 5825 "reflect.h2" +#line 5879 "reflect.h2" } -#line 5831 "reflect.h2" +#line 5885 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9738,7 +9801,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5841 "reflect.h2" +#line 5895 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9746,17 +9809,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 5848 "reflect.h2" +#line 5902 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 5852 "reflect.h2" +#line 5906 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 5859 "reflect.h2" +#line 5913 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9766,7 +9829,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 5868 "reflect.h2" +#line 5922 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -9774,24 +9837,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 5875 "reflect.h2" +#line 5929 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 5883 "reflect.h2" +#line 5937 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 5887 "reflect.h2" +#line 5941 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 5891 "reflect.h2" +#line 5945 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -9803,22 +9866,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 5902 "reflect.h2" +#line 5956 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 5908 "reflect.h2" +#line 5962 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 5912 "reflect.h2" +#line 5966 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 5916 "reflect.h2" +#line 5970 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -9826,7 +9889,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5923 "reflect.h2" +#line 5977 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -9838,10 +9901,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5936 "reflect.h2" +#line 5990 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 5939 "reflect.h2" +#line 5993 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -9881,7 +9944,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 5979 "reflect.h2" +#line 6033 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -9893,14 +9956,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 5990 "reflect.h2" +#line 6044 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 5991 "reflect.h2" +#line 6045 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 5992 "reflect.h2" +#line 6046 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 5994 "reflect.h2" +#line 6048 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -9910,10 +9973,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6003 "reflect.h2" +#line 6057 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6005 "reflect.h2" +#line 6059 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -9935,14 +9998,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6026 "reflect.h2" +#line 6080 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6027 "reflect.h2" +#line 6081 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6028 "reflect.h2" +#line 6082 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6030 "reflect.h2" +#line 6084 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -9956,7 +10019,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6043 "reflect.h2" +#line 6097 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -9978,7 +10041,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6064 "reflect.h2" +#line 6118 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -9989,12 +10052,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6074 "reflect.h2" +#line 6128 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6075 "reflect.h2" +#line 6129 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6080 "reflect.h2" +#line 6134 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10049,7 +10112,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6134 "reflect.h2" +#line 6188 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10089,7 +10152,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6173 "reflect.h2" +#line 6227 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10105,21 +10168,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6190 "reflect.h2" +#line 6244 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6191 "reflect.h2" +#line 6245 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6192 "reflect.h2" +#line 6246 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6194 "reflect.h2" +#line 6248 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6209 "reflect.h2" +#line 6263 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10127,7 +10190,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6216 "reflect.h2" +#line 6270 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10137,22 +10200,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6234 "reflect.h2" +#line 6288 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6239 "reflect.h2" +#line 6293 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6245 "reflect.h2" +#line 6299 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6251 "reflect.h2" +#line 6305 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10161,7 +10224,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6259 "reflect.h2" +#line 6313 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10173,7 +10236,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6270 "reflect.h2" +#line 6324 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10181,7 +10244,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6277 "reflect.h2" +#line 6331 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10202,7 +10265,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6298 "reflect.h2" +#line 6352 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10212,7 +10275,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6308 "reflect.h2" +#line 6362 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10235,33 +10298,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6332 "reflect.h2" +#line 6386 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6338 "reflect.h2" +#line 6392 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6342 "reflect.h2" +#line 6396 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6348 "reflect.h2" +#line 6402 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6356 "reflect.h2" +#line 6410 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10270,7 +10333,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6364 "reflect.h2" +#line 6418 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10279,22 +10342,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6374 "reflect.h2" +#line 6428 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6378 "reflect.h2" +#line 6432 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6382 "reflect.h2" +#line 6436 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6386 "reflect.h2" +#line 6440 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10318,18 +10381,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6411 "reflect.h2" +#line 6465 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6426 "reflect.h2" +#line 6480 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6428 "reflect.h2" +#line 6482 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10340,15 +10403,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6443 "reflect.h2" +#line 6497 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6446 "reflect.h2" +#line 6500 "reflect.h2" } -#line 6448 "reflect.h2" +#line 6502 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10366,7 +10429,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6465 "reflect.h2" +#line 6519 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10374,7 +10437,7 @@ generation_function_context::generation_function_context(){} } } -#line 6472 "reflect.h2" +#line 6526 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10388,7 +10451,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6485 "reflect.h2" +#line 6539 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10404,14 +10467,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6506 "reflect.h2" +#line 6560 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6508 "reflect.h2" +#line 6562 "reflect.h2" } -#line 6510 "reflect.h2" +#line 6564 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10420,11 +10483,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6525 "reflect.h2" +#line 6579 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6527 "reflect.h2" +#line 6581 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10432,7 +10495,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6534 "reflect.h2" +#line 6588 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10441,37 +10504,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6542 "reflect.h2" +#line 6596 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6556 "reflect.h2" +#line 6610 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6560 "reflect.h2" +#line 6614 "reflect.h2" } -#line 6562 "reflect.h2" +#line 6616 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6566 "reflect.h2" +#line 6620 "reflect.h2" } -#line 6568 "reflect.h2" +#line 6622 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6572 "reflect.h2" +#line 6626 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10480,14 +10543,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6578 "reflect.h2" +#line 6632 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6583 "reflect.h2" +#line 6637 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10500,7 +10563,7 @@ size_t i{0}; } } -#line 6595 "reflect.h2" +#line 6649 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10522,7 +10585,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6616 "reflect.h2" +#line 6670 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10541,7 +10604,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6634 "reflect.h2" +#line 6688 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10557,14 +10620,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6649 "reflect.h2" +#line 6703 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6655 "reflect.h2" +#line 6709 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10572,19 +10635,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6672 "reflect.h2" +#line 6726 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6673 "reflect.h2" +#line 6727 "reflect.h2" { -#line 6678 "reflect.h2" +#line 6732 "reflect.h2" } -#line 6681 "reflect.h2" +#line 6735 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10710,7 +10773,7 @@ size_t i{0}; ); } -#line 6806 "reflect.h2" +#line 6860 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10720,13 +10783,13 @@ size_t i{0}; ); } -#line 6815 "reflect.h2" +#line 6869 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 6820 "reflect.h2" +#line 6874 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10737,12 +10800,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 6832 "reflect.h2" +#line 6886 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 6837 "reflect.h2" +#line 6891 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -10776,7 +10839,7 @@ size_t i{0}; } -#line 6873 "reflect.h2" +#line 6927 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -10785,19 +10848,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 6896 "reflect.h2" +#line 6950 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 6897 "reflect.h2" +#line 6951 "reflect.h2" { -#line 6902 "reflect.h2" +#line 6956 "reflect.h2" } -#line 6904 "reflect.h2" +#line 6958 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -10899,19 +10962,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7005 "reflect.h2" +#line 7059 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7009 "reflect.h2" +#line 7063 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7033 "reflect.h2" +#line 7087 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10930,7 +10993,7 @@ size_t i{0}; return r; } -#line 7051 "reflect.h2" +#line 7105 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -10945,7 +11008,7 @@ size_t i{0}; return r; } -#line 7065 "reflect.h2" +#line 7119 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11105,7 +11168,7 @@ size_t i{0}; } } -#line 7224 "reflect.h2" +#line 7278 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11114,7 +11177,7 @@ size_t i{0}; return r; } -#line 7232 "reflect.h2" +#line 7286 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11133,7 +11196,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7250 "reflect.h2" +#line 7304 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11165,7 +11228,7 @@ size_t i{0}; } } -#line 7281 "reflect.h2" +#line 7335 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11176,7 +11239,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7293 "reflect.h2" +#line 7347 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11215,7 +11278,7 @@ size_t i{0}; return r; } -#line 7334 "reflect.h2" +#line 7388 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11233,7 +11296,7 @@ size_t i{0}; }} } -#line 7354 "reflect.h2" +#line 7408 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11247,16 +11310,16 @@ size_t i{0}; } } -#line 7380 "reflect.h2" +#line 7434 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7383 "reflect.h2" +#line 7437 "reflect.h2" } -#line 7385 "reflect.h2" +#line 7439 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11268,7 +11331,7 @@ size_t i{0}; } } -#line 7396 "reflect.h2" +#line 7450 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11276,14 +11339,14 @@ size_t i{0}; return r; } -#line 7403 "reflect.h2" +#line 7457 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7411 "reflect.h2" +#line 7465 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11309,7 +11372,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7439 "reflect.h2" +#line 7493 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11335,11 +11398,11 @@ size_t i{0}; return r; } -#line 7476 "reflect.h2" +#line 7530 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7478 "reflect.h2" +#line 7532 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11413,7 +11476,7 @@ size_t i{0}; return nullptr; } -#line 7551 "reflect.h2" +#line 7605 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11426,7 +11489,7 @@ size_t i{0}; }} } -#line 7563 "reflect.h2" +#line 7617 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11440,7 +11503,7 @@ size_t i{0}; }} } -#line 7576 "reflect.h2" +#line 7630 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11460,7 +11523,7 @@ size_t i{0}; return r; } -#line 7595 "reflect.h2" +#line 7649 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11471,7 +11534,7 @@ size_t i{0}; return r; } -#line 7605 "reflect.h2" +#line 7659 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11483,14 +11546,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7616 "reflect.h2" +#line 7670 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7628 "reflect.h2" +#line 7682 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11514,7 +11577,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7652 "reflect.h2" +#line 7706 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11524,7 +11587,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7664 "reflect.h2" +#line 7718 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11540,7 +11603,7 @@ size_t i{0}; } } -#line 7684 "reflect.h2" +#line 7738 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11558,15 +11621,15 @@ size_t i{0}; }} } -#line 7720 "reflect.h2" +#line 7774 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7723 "reflect.h2" +#line 7777 "reflect.h2" } -#line 7725 "reflect.h2" +#line 7779 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11602,7 +11665,7 @@ size_t i{0}; return source; } -#line 7760 "reflect.h2" +#line 7814 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11618,7 +11681,7 @@ size_t i{0}; } } -#line 7776 "reflect.h2" +#line 7830 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11627,7 +11690,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11682,7 +11745,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 7845 "reflect.h2" +#line 7899 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -11804,7 +11867,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 7967 "reflect.h2" +#line 8021 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 5bf87121c..0b3a1fa12 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4469,6 +4469,15 @@ autodiff_expression_handler: type = { } } + prepare_backprop: (this, rhs_b: std::string, lhs: std::string, lhs_d: std::string, lhs_b: std::string) -> std::string = { + r := rhs_b; + r = string_util::replace_all(r, "_r_", lhs); + r = string_util::replace_all(r, "_rd_", lhs_d); + r = string_util::replace_all(r, "_rb_", lhs_b); + + return r; + } + gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string) = { diff.add_forward("(lhs_d)$ = (rhs_d)$;\n"); diff.add_forward("(lhs)$ = (rhs)$;\n"); @@ -4477,7 +4486,7 @@ autodiff_expression_handler: type = { diff.add_reverse_primal("(lhs_d)$ = (rhs_d)$;\n"); } diff.add_reverse_primal("(lhs)$ = (rhs)$;\n"); - diff.add_reverse_backprop(string_util::replace_all(rhs_b, "_rb_", lhs_b)); + diff.add_reverse_backprop(prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string) = gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); @@ -4485,16 +4494,22 @@ autodiff_expression_handler: type = { = gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, ctx*.fwd_suffix), add_suffix_if_not_wildcard(lhs, ctx*.rws_suffix), primal_expr, fwd_expr, rws_expr); - gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string, type_d: std::string) = { - diff += "(lhs_d)$: (type_d)$ = (rhs_d)$;\n"; - diff += "(lhs)$ : (type)$ = (rhs)$;\n"; + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string, type: std::string, type_d: std::string, type_b: std::string) = { + diff.add_forward("(lhs_d)$: (type_d)$ = (rhs_d)$;\n"); + diff.add_forward("(lhs)$ : (type)$ = (rhs)$;\n"); + + if ctx*.is_taylor() { + diff.add_reverse_primal("(lhs_d)$: (type_d)$ = (rhs_d)$;\n"); + } + diff.add_reverse_primal("(lhs)$ : (type)$ = (rhs)$;\n"); + diff.add_reverse_backprop(prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } - gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, rhs: std::string, rhs_d: std::string, type: std::string) - = gen_declaration(lhs, lhs_d, rhs, rhs_d, type, ctx*.get_fwd_ad_type(type)); - gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, type: std::string) - = gen_declaration(lhs, lhs_d, primal_expr, fwd_expr, type, ctx*.get_fwd_ad_type(type)); + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string, type: std::string) + = gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, ctx*.get_fwd_ad_type(type) , ctx*.get_rws_ad_type(type)); + gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, type: std::string) + = gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); gen_declaration: (inout this, lhs: std::string, type: std::string) - = gen_declaration(lhs, lhs + ctx*.fwd_suffix, primal_expr, fwd_expr, type, ctx*.get_fwd_ad_type(type)); + = gen_declaration(lhs, lhs + ctx*.fwd_suffix, lhs + ctx*.rws_suffix, type); @@ -4824,33 +4839,44 @@ autodiff_expression_handler: type = { var := handle_expression_term(terms[0].get_term()); arg_a := var.primal; arg_a_d := var.fwd; + arg_a_b := var.rws; i : int = 1; while i < terms.ssize() next i += 1 { var = handle_expression_term(terms[i].get_term()); arg_b := var.primal; arg_b_d := var.fwd; + arg_b_b := var.rws; op := terms[i].get_op().to_string(); fwd : std::string = ""; + rws : std::string = ""; primal : std::string = ""; if "*" == op { if ctx*.is_taylor() { - fwd = "(arg_a_d)$.mul((arg_b_d)$, (arg_a)$, (arg_b)$)"; + fwd = "(arg_a_d)$..mul((arg_b_d)$, (arg_a)$, (arg_b)$)"; + rws = "(arg_b_b)$ += (arg_a_d)$..mul(_rb_, (arg_a)$, _r_);\n" + "(arg_a_b)$ += (arg_b_d)$..mul(_rb_, (arg_b)$, _r_);"; } else { fwd = "(arg_a)$ * (arg_b_d)$ + (arg_b)$ * (arg_a_d)$"; + rws = "(arg_b_b)$ += (arg_a)$ * _rb_;\n" + "(arg_a_b)$ += (arg_b)$ * _rb_;"; } primal = "(arg_a)$ * (arg_b)$"; } else if "/" == op { if ctx*.is_taylor() { fwd = "(arg_a_d)$.div((arg_b_d)$, (arg_a)$, (arg_b)$)"; + rws = "(arg_b_b)$ -= (arg_a_d)$.mul(_rb_, (arg_a)$, _r_).div((arg_b_d)$.mul((arg_b_d)$, (arg_b)$, (arg_b)$), (arg_a)$ * _r_, (arg_b)$ * (arg_b)$);\n" + "(arg_a_b)$ += _rb_.div((arg_b_d)$, _r_, (arg_b)$);"; } else { - fwd = "(arg_a_d)$ / (arg_b)$ - (arg_a)$ * (arg_b_d)$ / ((arg_b)$ * (arg_b)$)"; + fwd = "(arg_a_d)$ / (arg_b)$ - (arg_a)$ * (arg_b_d)$ / ((arg_b)$ * (arg_b)$)"; + rws = "(arg_b_b)$ -= (arg_a)$ * _rb_ / ((arg_b)$ * (arg_b)$);\n" + "(arg_a_b)$ += _rb_ / (arg_b)$;"; } primal = "(arg_a)$ / (arg_b)$"; } @@ -4862,15 +4888,18 @@ autodiff_expression_handler: type = { if i + 1 == terms.ssize() { primal_expr = primal; fwd_expr = fwd; + rws_expr = rws; } else { // Temporary t := ctx*.gen_temporary(); t_d := t + ctx*.fwd_suffix; - gen_declaration(t, t_d, primal, fwd, "", ""); + t_b := t + ctx*.rws_suffix; + gen_declaration(t, t_d, t_b, primal, fwd, rws, "", "", ""); arg_a = t; arg_a_d = t_d; + arg_a_b = t_b; } } } From ff18571a2e5ae2eeedcd708f315757ab4501d23b Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Thu, 28 Aug 2025 13:53:27 +0200 Subject: [PATCH 43/54] Fix for to_string of expressions. --- source/parse.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/parse.h b/source/parse.h index 9d0d7dbeb..fd8b1a6f9 100644 --- a/source/parse.h +++ b/source/parse.h @@ -2196,7 +2196,9 @@ auto postfix_expression_node::to_string() const for (auto const& x : ops) { assert (x.op); - ret += x.op->as_string_view(); + if(x.op->as_string_view() != "(") { // Brackets are handled by the expression list. + ret += x.op->as_string_view(); + } if (x.id_expr) { ret += x.id_expr->to_string(); } From cae65f19f541b50c847eeef4609f1a9fcd9e5c9f Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Thu, 28 Aug 2025 13:55:25 +0200 Subject: [PATCH 44/54] Activity analysis for variables and functions. --- source/reflect.h | 1875 +++++++++++++++++++++++++-------------------- source/reflect.h2 | 350 +++++++-- 2 files changed, 1320 insertions(+), 905 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index d93e69095..537c59b01 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -114,102 +114,106 @@ class autodiff_special_func; #line 4127 "reflect.h2" class autodiff_declared_variable; -#line 4143 "reflect.h2" +#line 4145 "reflect.h2" class autodiff_declaration_stack_item; -#line 4182 "reflect.h2" +#line 4184 "reflect.h2" class autodiff_context; -#line 4514 "reflect.h2" +#line 4547 "reflect.h2" class autodiff_diff_code; -#line 4562 "reflect.h2" +#line 4595 "reflect.h2" +class autodiff_activity_check; + + +#line 4681 "reflect.h2" class autodiff_handler_base; -#line 4580 "reflect.h2" +#line 4699 "reflect.h2" class autodiff_expression_handler; -#line 5135 "reflect.h2" +#line 5286 "reflect.h2" class autodiff_stmt_handler; -#line 5396 "reflect.h2" +#line 5569 "reflect.h2" class autodiff_declaration_handler; -#line 5730 "reflect.h2" +#line 5914 "reflect.h2" class expression_flags; -#line 5746 "reflect.h2" +#line 5930 "reflect.h2" class regex_token; -#line 5773 "reflect.h2" +#line 5957 "reflect.h2" class regex_token_check; -#line 5794 "reflect.h2" +#line 5978 "reflect.h2" class regex_token_code; -#line 5815 "reflect.h2" +#line 5999 "reflect.h2" class regex_token_empty; -#line 5833 "reflect.h2" +#line 6017 "reflect.h2" class regex_token_list; -#line 5885 "reflect.h2" +#line 6069 "reflect.h2" class parse_context_group_state; -#line 5946 "reflect.h2" +#line 6130 "reflect.h2" class parse_context_branch_reset_state; -#line 5989 "reflect.h2" +#line 6173 "reflect.h2" class parse_context; -#line 6390 "reflect.h2" +#line 6574 "reflect.h2" class generation_function_context; -#line 6408 "reflect.h2" +#line 6592 "reflect.h2" class generation_context; -#line 6607 "reflect.h2" +#line 6791 "reflect.h2" class alternative_token; -#line 6622 "reflect.h2" +#line 6806 "reflect.h2" class alternative_token_gen; -#line 6687 "reflect.h2" +#line 6871 "reflect.h2" class any_token; -#line 6704 "reflect.h2" +#line 6888 "reflect.h2" class atomic_group_token; -#line 6734 "reflect.h2" +#line 6918 "reflect.h2" class char_token; -#line 6849 "reflect.h2" +#line 7033 "reflect.h2" class class_token; -#line 7073 "reflect.h2" +#line 7257 "reflect.h2" class group_ref_token; -#line 7210 "reflect.h2" +#line 7394 "reflect.h2" class group_token; -#line 7557 "reflect.h2" +#line 7741 "reflect.h2" class lookahead_lookbehind_token; -#line 7652 "reflect.h2" +#line 7836 "reflect.h2" class range_token; -#line 7809 "reflect.h2" +#line 7993 "reflect.h2" class special_range_token; -#line 7895 "reflect.h2" +#line 8079 "reflect.h2" template class regex_generator; -#line 8158 "reflect.h2" +#line 8342 "reflect.h2" } } @@ -258,12 +262,12 @@ class compiler_services #line 47 "reflect.h2" public: compiler_services( - std::vector* errors_, - std::set* includes_, - std::vector* extra_cpp1_, - std::vector* extra_build_, + cpp2::impl::in*> errors_, + cpp2::impl::in*> includes_, + cpp2::impl::in*> extra_cpp1_, + cpp2::impl::in*> extra_build_, cpp2::impl::in filename, - stable_vector* generated_tokens_ + cpp2::impl::in*> generated_tokens_ ); #line 69 "reflect.h2" @@ -330,7 +334,7 @@ template class reflection_base protected: reflection_base( - T* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -355,7 +359,7 @@ class declaration #line 252 "reflect.h2" public: declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -434,7 +438,7 @@ class function_declaration #line 337 "reflect.h2" public: function_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -511,7 +515,7 @@ class object_declaration #line 442 "reflect.h2" public: object_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -537,7 +541,7 @@ class type_or_namespace_declaration #line 478 "reflect.h2" public: type_or_namespace_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -578,7 +582,7 @@ class type_declaration #line 589 "reflect.h2" public: type_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -613,7 +617,7 @@ class namespace_declaration #line 633 "reflect.h2" public: namespace_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); public: namespace_declaration(namespace_declaration const& that); @@ -630,7 +634,7 @@ class alias_declaration #line 652 "reflect.h2" public: alias_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); public: alias_declaration(alias_declaration const& that); @@ -647,7 +651,7 @@ class parameter_declaration #line 671 "reflect.h2" public: parameter_declaration( - parameter_declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -685,7 +689,7 @@ template class binary_expression #line 717 "reflect.h2" public: binary_expression( - binary_expression_node* n_, + binary_expression_node* const& n_, cpp2::impl::in s ); @@ -746,7 +750,7 @@ class expression_list #line 844 "reflect.h2" public: expression_list( - expression_list_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -771,7 +775,7 @@ class prefix_expression #line 877 "reflect.h2" public: prefix_expression( - prefix_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -808,7 +812,7 @@ class postfix_expression #line 919 "reflect.h2" public: postfix_expression( - postfix_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -871,7 +875,7 @@ class template_arg #line 990 "reflect.h2" public: template_arg( - template_argument* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -896,7 +900,7 @@ class unqualified_id #line 1016 "reflect.h2" public: unqualified_id( - unqualified_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -922,7 +926,7 @@ class qualified_id #line 1048 "reflect.h2" public: qualified_id( - qualified_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -960,7 +964,7 @@ class type_id #line 1092 "reflect.h2" public: type_id( - type_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -996,7 +1000,7 @@ class primary_expression #line 1135 "reflect.h2" public: primary_expression( - primary_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1028,7 +1032,7 @@ class id_expression #line 1174 "reflect.h2" public: id_expression( - id_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1058,7 +1062,7 @@ class expression #line 1210 "reflect.h2" public: expression( - expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1102,7 +1106,7 @@ class is_as_expression #line 1261 "reflect.h2" public: is_as_expression( - is_as_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1154,7 +1158,7 @@ class statement #line 1322 "reflect.h2" public: statement( - statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1193,7 +1197,7 @@ class expression_statement #line 1364 "reflect.h2" public: expression_statement( - expression_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1214,7 +1218,7 @@ class compound_statement #line 1386 "reflect.h2" public: compound_statement( - compound_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1237,7 +1241,7 @@ class selection_statement #line 1425 "reflect.h2" public: selection_statement( - selection_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1262,7 +1266,7 @@ class return_statement #line 1451 "reflect.h2" public: return_statement( - return_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1283,7 +1287,7 @@ class iteration_statement #line 1473 "reflect.h2" public: iteration_statement( - iteration_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ); @@ -1710,19 +1714,20 @@ class autodiff_special_func { class autodiff_declared_variable { public: std::string name {""}; public: std::string decl {""}; + public: bool is_active {false}; public: bool is_member {false}; public: explicit autodiff_declared_variable(); - public: autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_member_); + public: autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_active_, cpp2::impl::in is_member_); -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" public: autodiff_declared_variable(autodiff_declared_variable const& that); -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" public: auto operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& ; -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" public: autodiff_declared_variable(autodiff_declared_variable&& that) noexcept; -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" public: auto operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& ; }; @@ -1739,25 +1744,25 @@ class autodiff_declaration_stack_item { using lookup_declaration_ret = std::vector; -#line 4157 "reflect.h2" +#line 4159 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; struct lookup_variable_declaration_ret { bool found; autodiff_declared_variable r; }; -#line 4167 "reflect.h2" +#line 4169 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret; public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4180 "reflect.h2" +#line 4182 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4192 "reflect.h2" +#line 4194 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, false, "sin(_a1_)", @@ -1778,17 +1783,23 @@ class autodiff_context { "exp(_a1_)", "_ad1_.exp(_a1_)" ), + autodiff_special_func("sqrt", 1, false, + "sqrt(_a1_)", + "0.5 * _ad1_ / sqrt(_a1_)", + "sqrt(_a1_)", + "_ad1_.sqrt(_a1_)" + ), autodiff_special_func("push_back", 1, true, "_o_.push_back(_a1_);", "_od_.push_back(_ad1_);")}; -#line 4217 "reflect.h2" +#line 4225 "reflect.h2" public: std::string fwd_suffix {"_d"}; public: std::string rws_suffix {"_b"}; private: int order {1}; public: bool reverse {false}; -#line 4223 "reflect.h2" +#line 4231 "reflect.h2" public: std::string fwd_ad_type {"double"}; public: std::string rws_ad_type {"double"}; @@ -1798,85 +1809,91 @@ class autodiff_context { public: explicit autodiff_context(); public: autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_); -#line 4246 "reflect.h2" - public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member = false) & -> void; +#line 4254 "reflect.h2" + public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member = false) & -> void; + +#line 4258 "reflect.h2" + public: [[nodiscard]] auto is_variable_active(cpp2::impl::in name) & -> bool; -#line 4250 "reflect.h2" +#line 4262 "reflect.h2" public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4267 "reflect.h2" +#line 4279 "reflect.h2" public: [[nodiscard]] auto is_forward() const& -> decltype(auto); public: [[nodiscard]] auto is_reverse() const& -> decltype(auto); public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4276 "reflect.h2" +#line 4288 "reflect.h2" + public: [[nodiscard]] auto is_type_active(cpp2::impl::in type) & -> bool; + +#line 4309 "reflect.h2" public: [[nodiscard]] auto get_fwd_ad_type(cpp2::impl::in type) & -> std::string; -#line 4294 "reflect.h2" +#line 4327 "reflect.h2" public: [[nodiscard]] auto get_rws_ad_type(cpp2::impl::in type) & -> std::string; -#line 4312 "reflect.h2" +#line 4345 "reflect.h2" public: [[nodiscard]] auto get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style; using lookup_declaration_ret = std::vector; -#line 4340 "reflect.h2" +#line 4373 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; -#line 4363 "reflect.h2" +#line 4396 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4380 "reflect.h2" +#line 4413 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; using lookup_member_function_declaration_ret = std::vector; -#line 4390 "reflect.h2" +#line 4423 "reflect.h2" public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4400 "reflect.h2" +#line 4433 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; -#line 4410 "reflect.h2" +#line 4443 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4432 "reflect.h2" +#line 4465 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4440 "reflect.h2" +#line 4473 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4460 "reflect.h2" +#line 4493 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4470 "reflect.h2" +#line 4503 "reflect.h2" public: auto enter_function() & -> void; -#line 4475 "reflect.h2" +#line 4508 "reflect.h2" public: auto leave_function() & -> void; -#line 4479 "reflect.h2" +#line 4512 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4492 "reflect.h2" +#line 4525 "reflect.h2" public: auto pop_stack() & -> void; -#line 4507 "reflect.h2" +#line 4540 "reflect.h2" public: auto finish() & -> void; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4512 "reflect.h2" +#line 4545 "reflect.h2" }; class autodiff_diff_code { @@ -1886,268 +1903,292 @@ class autodiff_diff_code { public: std::string rws_primal {""}; public: std::string rws_backprop {""}; - public: autodiff_diff_code(autodiff_context* ctx_); -#line 4521 "reflect.h2" - public: auto operator=(autodiff_context* ctx_) -> autodiff_diff_code& ; + public: autodiff_diff_code(cpp2::impl::in ctx_); +#line 4554 "reflect.h2" + public: auto operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& ; -#line 4525 "reflect.h2" +#line 4558 "reflect.h2" public: auto add_forward(cpp2::impl::in v) & -> void; public: auto add_reverse_primal(cpp2::impl::in v) & -> void; public: auto add_reverse_backprop(cpp2::impl::in v) & -> void; public: auto reset() & -> void; -#line 4536 "reflect.h2" +#line 4569 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4542 "reflect.h2" +#line 4575 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4547 "reflect.h2" +#line 4580 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4552 "reflect.h2" +#line 4585 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_diff_code const&) -> void = delete; -#line 4555 "reflect.h2" +#line 4588 "reflect.h2" +}; + +#line 4595 "reflect.h2" +class autodiff_activity_check: public simple_traverser { + +#line 4598 "reflect.h2" + public: autodiff_context* ctx; + public: bool active {false}; + + public: autodiff_activity_check(cpp2::impl::in ctx_); + +#line 4605 "reflect.h2" + public: auto traverse(cpp2::impl::in o) -> void override; + +#line 4623 "reflect.h2" + public: auto traverse(cpp2::impl::in primary) -> void override; + +#line 4647 "reflect.h2" + public: auto traverse(cpp2::impl::in postfix) -> void override; + public: autodiff_activity_check(autodiff_activity_check const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(autodiff_activity_check const&) -> void = delete; + + +#line 4679 "reflect.h2" }; -#line 4562 "reflect.h2" class autodiff_handler_base { public: autodiff_context* ctx; public: autodiff_diff_code diff; - public: autodiff_handler_base(autodiff_context* ctx_); -#line 4567 "reflect.h2" - public: auto operator=(autodiff_context* ctx_) -> autodiff_handler_base& ; + public: autodiff_handler_base(cpp2::impl::in ctx_); +#line 4686 "reflect.h2" + public: auto operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& ; -#line 4573 "reflect.h2" +#line 4692 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4578 "reflect.h2" +#line 4697 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4584 "reflect.h2" +#line 4703 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; public: std::string fwd_expr {""}; public: std::string rws_expr {""}; - public: autodiff_expression_handler(autodiff_context* ctx_); + public: autodiff_expression_handler(cpp2::impl::in ctx_); -#line 4594 "reflect.h2" +#line 4713 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; -#line 4603 "reflect.h2" +#line 4722 "reflect.h2" public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; -#line 4612 "reflect.h2" +#line 4731 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4622 "reflect.h2" +#line 4741 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4628 "reflect.h2" +#line 4747 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4638 "reflect.h2" +#line 4757 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4647 "reflect.h2" +#line 4766 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; public: std::string rws {""}; - public: primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_) -CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; + public: bool active {false}; + public: primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_, auto&& active_) +CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_rws_name(); -#line 4651 "reflect.h2" +#line 4771 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4662 "reflect.h2" +#line 4782 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4715 "reflect.h2" +#line 4843 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4859 "reflect.h2" +#line 4992 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 4894 "reflect.h2" +#line 5027 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 4898 "reflect.h2" +#line 5031 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4902 "reflect.h2" +#line 5035 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4906 "reflect.h2" +#line 5039 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4910 "reflect.h2" +#line 5043 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4914 "reflect.h2" +#line 5047 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4918 "reflect.h2" +#line 5051 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4922 "reflect.h2" +#line 5055 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4926 "reflect.h2" +#line 5059 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4930 "reflect.h2" +#line 5063 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4934 "reflect.h2" +#line 5067 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4938 "reflect.h2" +#line 5071 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 4967 "reflect.h2" +#line 5102 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5038 "reflect.h2" +#line 5189 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5042 "reflect.h2" +#line 5193 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5058 "reflect.h2" +#line 5209 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5098 "reflect.h2" +#line 5249 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5133 "reflect.h2" +#line 5284 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5139 "reflect.h2" +#line 5290 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; - public: autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_); + public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5148 "reflect.h2" +#line 5299 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5153 "reflect.h2" +#line 5304 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5158 "reflect.h2" +#line 5309 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5187 "reflect.h2" +#line 5360 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5192 "reflect.h2" +#line 5365 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5197 "reflect.h2" +#line 5370 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5202 "reflect.h2" +#line 5375 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5210 "reflect.h2" +#line 5383 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5227 "reflect.h2" +#line 5400 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5277 "reflect.h2" +#line 5450 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5288 "reflect.h2" +#line 5461 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5292 "reflect.h2" +#line 5465 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5305 "reflect.h2" +#line 5478 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5309 "reflect.h2" +#line 5482 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5313 "reflect.h2" +#line 5486 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5317 "reflect.h2" +#line 5490 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5321 "reflect.h2" +#line 5494 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5325 "reflect.h2" +#line 5498 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5329 "reflect.h2" +#line 5502 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5333 "reflect.h2" +#line 5506 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5337 "reflect.h2" +#line 5510 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5341 "reflect.h2" +#line 5514 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5345 "reflect.h2" +#line 5518 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5349 "reflect.h2" +#line 5522 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5353 "reflect.h2" +#line 5526 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5358 "reflect.h2" +#line 5531 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5390 "reflect.h2" +#line 5563 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5394 "reflect.h2" +#line 5567 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5400 "reflect.h2" +#line 5573 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2155,39 +2196,39 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han private: bool is_type_context {false}; private: std::string diff_ad_type {""}; - public: autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_); + public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5412 "reflect.h2" +#line 5585 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5417 "reflect.h2" +#line 5590 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5564 "reflect.h2" +#line 5748 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5592 "reflect.h2" +#line 5776 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5616 "reflect.h2" +#line 5800 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5621 "reflect.h2" +#line 5805 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5624 "reflect.h2" +#line 5808 "reflect.h2" }; -#line 5627 "reflect.h2" +#line 5811 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5726 "reflect.h2" +#line 5910 "reflect.h2" using error_func = std::function x)>; -#line 5730 "reflect.h2" +#line 5914 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2222,20 +2263,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5738 "reflect.h2" +#line 5922 "reflect.h2" }; -#line 5746 "reflect.h2" +#line 5930 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5754 "reflect.h2" +#line 5938 "reflect.h2" public: explicit regex_token(); -#line 5759 "reflect.h2" +#line 5943 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2247,103 +2288,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5765 "reflect.h2" +#line 5949 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5771 "reflect.h2" +#line 5955 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5777 "reflect.h2" +#line 5961 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5784 "reflect.h2" +#line 5968 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5788 "reflect.h2" +#line 5972 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5789 "reflect.h2" +#line 5973 "reflect.h2" }; -#line 5792 "reflect.h2" +#line 5976 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5798 "reflect.h2" +#line 5982 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5805 "reflect.h2" +#line 5989 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5809 "reflect.h2" +#line 5993 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5810 "reflect.h2" +#line 5994 "reflect.h2" }; -#line 5813 "reflect.h2" +#line 5997 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 5819 "reflect.h2" +#line 6003 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 5823 "reflect.h2" +#line 6007 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 5827 "reflect.h2" +#line 6011 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 5828 "reflect.h2" +#line 6012 "reflect.h2" }; -#line 5831 "reflect.h2" +#line 6015 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 5837 "reflect.h2" +#line 6021 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 5844 "reflect.h2" +#line 6028 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5850 "reflect.h2" +#line 6034 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 5856 "reflect.h2" +#line 6040 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 5864 "reflect.h2" +#line 6048 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2351,10 +2392,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 5876 "reflect.h2" +#line 6060 "reflect.h2" }; -#line 5879 "reflect.h2" +#line 6063 "reflect.h2" // // Parse and generation context. // @@ -2370,33 +2411,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 5899 "reflect.h2" +#line 6083 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 5906 "reflect.h2" +#line 6090 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 5918 "reflect.h2" +#line 6102 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 5923 "reflect.h2" +#line 6107 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 5927 "reflect.h2" +#line 6111 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 5941 "reflect.h2" +#line 6125 "reflect.h2" }; -#line 5944 "reflect.h2" +#line 6128 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2409,25 +2450,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 5962 "reflect.h2" +#line 6146 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 5968 "reflect.h2" +#line 6152 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 5975 "reflect.h2" +#line 6159 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 5982 "reflect.h2" +#line 6166 "reflect.h2" }; -#line 5985 "reflect.h2" +#line 6169 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2443,7 +2484,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6001 "reflect.h2" +#line 6185 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2451,64 +2492,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6012 "reflect.h2" +#line 6196 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6025 "reflect.h2" +#line 6209 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6033 "reflect.h2" +#line 6217 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6037 "reflect.h2" +#line 6221 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6041 "reflect.h2" +#line 6225 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6053 "reflect.h2" +#line 6237 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6060 "reflect.h2" +#line 6244 "reflect.h2" public: auto next_alternative() & -> void; -#line 6066 "reflect.h2" +#line 6250 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6072 "reflect.h2" +#line 6256 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6076 "reflect.h2" +#line 6260 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6087 "reflect.h2" +#line 6271 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6091 "reflect.h2" +#line 6275 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6097 "reflect.h2" +#line 6281 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6101 "reflect.h2" +#line 6285 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6108 "reflect.h2" +#line 6292 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6119 "reflect.h2" +#line 6303 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2516,51 +2557,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6163 "reflect.h2" +#line 6347 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6175 "reflect.h2" +#line 6359 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6188 "reflect.h2" +#line 6372 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6211 "reflect.h2" +#line 6395 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6228 "reflect.h2" +#line 6412 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6249 "reflect.h2" +#line 6433 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6259 "reflect.h2" +#line 6443 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6263 "reflect.h2" +#line 6447 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6319 "reflect.h2" +#line 6503 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6358 "reflect.h2" +#line 6542 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6373 "reflect.h2" +#line 6557 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2572,10 +2613,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6384 "reflect.h2" +#line 6568 "reflect.h2" }; -#line 6387 "reflect.h2" +#line 6571 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2585,16 +2626,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6401 "reflect.h2" +#line 6585 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6404 "reflect.h2" +#line 6588 "reflect.h2" }; -#line 6407 "reflect.h2" +#line 6591 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2614,68 +2655,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6429 "reflect.h2" +#line 6613 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6435 "reflect.h2" +#line 6619 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6444 "reflect.h2" +#line 6628 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6455 "reflect.h2" +#line 6639 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6462 "reflect.h2" +#line 6646 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6482 "reflect.h2" +#line 6666 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6492 "reflect.h2" +#line 6676 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6515 "reflect.h2" +#line 6699 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6523 "reflect.h2" +#line 6707 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6527 "reflect.h2" +#line 6711 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6533 "reflect.h2" +#line 6717 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6539 "reflect.h2" +#line 6723 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6549 "reflect.h2" +#line 6733 "reflect.h2" public: auto finish_context() & -> void; -#line 6557 "reflect.h2" +#line 6741 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6563 "reflect.h2" +#line 6747 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6567 "reflect.h2" +#line 6751 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6571 "reflect.h2" +#line 6755 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6595 "reflect.h2" +#line 6779 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2683,7 +2724,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6601 "reflect.h2" +#line 6785 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2703,27 +2744,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6620 "reflect.h2" +#line 6804 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6626 "reflect.h2" +#line 6810 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6633 "reflect.h2" +#line 6817 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6650 "reflect.h2" +#line 6834 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6657 "reflect.h2" +#line 6841 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6670 "reflect.h2" +#line 6854 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2731,19 +2772,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6682 "reflect.h2" +#line 6866 "reflect.h2" }; -#line 6685 "reflect.h2" +#line 6869 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6691 "reflect.h2" +#line 6875 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6695 "reflect.h2" +#line 6879 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2751,7 +2792,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6700 "reflect.h2" +#line 6884 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2759,17 +2800,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6708 "reflect.h2" +#line 6892 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6719 "reflect.h2" +#line 6903 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6727 "reflect.h2" +#line 6911 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2777,7 +2818,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6730 "reflect.h2" +#line 6914 "reflect.h2" }; // Regex syntax: a @@ -2785,34 +2826,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6738 "reflect.h2" +#line 6922 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6747 "reflect.h2" +#line 6931 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6753 "reflect.h2" +#line 6937 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6757 "reflect.h2" +#line 6941 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6780 "reflect.h2" +#line 6964 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6801 "reflect.h2" +#line 6985 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 6819 "reflect.h2" +#line 7003 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 6834 "reflect.h2" +#line 7018 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6840 "reflect.h2" +#line 7024 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2820,33 +2861,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 6844 "reflect.h2" +#line 7028 "reflect.h2" }; -#line 6847 "reflect.h2" +#line 7031 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 6853 "reflect.h2" +#line 7037 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 6865 "reflect.h2" +#line 7049 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6991 "reflect.h2" +#line 7175 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7000 "reflect.h2" +#line 7184 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7005 "reflect.h2" +#line 7189 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2854,20 +2895,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7012 "reflect.h2" +#line 7196 "reflect.h2" }; -#line 7015 "reflect.h2" +#line 7199 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7056 "reflect.h2" +#line 7240 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7067 "reflect.h2" +#line 7251 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2877,20 +2918,20 @@ class class_token class group_ref_token : public regex_token { -#line 7077 "reflect.h2" +#line 7261 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7089 "reflect.h2" +#line 7273 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7190 "reflect.h2" +#line 7374 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7194 "reflect.h2" +#line 7378 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2898,10 +2939,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7197 "reflect.h2" +#line 7381 "reflect.h2" }; -#line 7200 "reflect.h2" +#line 7384 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2915,29 +2956,29 @@ class group_ref_token class group_token : public regex_token { -#line 7214 "reflect.h2" +#line 7398 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7236 "reflect.h2" +#line 7420 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7250 "reflect.h2" +#line 7434 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7409 "reflect.h2" +#line 7593 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7417 "reflect.h2" +#line 7601 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7435 "reflect.h2" +#line 7619 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7466 "reflect.h2" +#line 7650 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2946,25 +2987,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7473 "reflect.h2" +#line 7657 "reflect.h2" }; -#line 7476 "reflect.h2" +#line 7660 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7517 "reflect.h2" +#line 7701 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7537 "reflect.h2" +#line 7721 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7553 "reflect.h2" +#line 7737 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -2972,20 +3013,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7561 "reflect.h2" +#line 7745 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7570 "reflect.h2" +#line 7754 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7581 "reflect.h2" +#line 7765 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7588 "reflect.h2" +#line 7772 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -2993,26 +3034,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7591 "reflect.h2" +#line 7775 "reflect.h2" }; -#line 7594 "reflect.h2" +#line 7778 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7622 "reflect.h2" +#line 7806 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7650 "reflect.h2" +#line 7834 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7656 "reflect.h2" +#line 7840 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3022,22 +3063,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7736 "reflect.h2" +#line 7920 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7748 "reflect.h2" +#line 7932 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7761 "reflect.h2" +#line 7945 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7780 "reflect.h2" +#line 7964 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7790 "reflect.h2" +#line 7974 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7801 "reflect.h2" +#line 7985 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3045,16 +3086,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7804 "reflect.h2" +#line 7988 "reflect.h2" }; -#line 7807 "reflect.h2" +#line 7991 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7813 "reflect.h2" +#line 7997 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3063,7 +3104,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 7843 "reflect.h2" +#line 8027 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3072,14 +3113,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 7865 "reflect.h2" +#line 8049 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 7887 "reflect.h2" +#line 8071 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3100,24 +3141,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 7910 "reflect.h2" +#line 8094 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 7945 "reflect.h2" +#line 8129 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 7959 "reflect.h2" +#line 8143 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 7971 "reflect.h2" +#line 8155 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8026 "reflect.h2" +#line 8210 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3128,7 +3169,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8158 "reflect.h2" +#line 8342 "reflect.h2" } } @@ -3161,12 +3202,12 @@ namespace meta { #line 47 "reflect.h2" compiler_services::compiler_services( - std::vector* errors_, - std::set* includes_, - std::vector* extra_cpp1_, - std::vector* extra_build_, + cpp2::impl::in*> errors_, + cpp2::impl::in*> includes_, + cpp2::impl::in*> extra_cpp1_, + cpp2::impl::in*> extra_build_, cpp2::impl::in filename, - stable_vector* generated_tokens_ + cpp2::impl::in*> generated_tokens_ ) : errors{ errors_ } , includes{ includes_ } @@ -3377,7 +3418,7 @@ compiler_services::compiler_services(compiler_services&& that) noexcept #line 218 "reflect.h2" template reflection_base::reflection_base( - T* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : compiler_services{ s } @@ -3423,7 +3464,7 @@ template reflection_base::reflection_base(reflection_base&& that #line 252 "reflect.h2" declaration::declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -3558,7 +3599,7 @@ declaration::declaration(declaration&& that) noexcept #line 337 "reflect.h2" function_declaration::function_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : declaration{ n_, s } @@ -3714,7 +3755,7 @@ function_declaration::function_declaration(function_declaration&& that) noexcept #line 442 "reflect.h2" object_declaration::object_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : declaration{ n_, s } @@ -3758,7 +3799,7 @@ object_declaration::object_declaration(object_declaration&& that) noexcept #line 478 "reflect.h2" type_or_namespace_declaration::type_or_namespace_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : declaration{ n_, s } @@ -3879,7 +3920,7 @@ type_or_namespace_declaration::type_or_namespace_declaration(type_or_namespace_d #line 589 "reflect.h2" type_declaration::type_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } @@ -3933,7 +3974,7 @@ type_declaration::type_declaration(type_declaration&& that) noexcept #line 633 "reflect.h2" namespace_declaration::namespace_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : type_or_namespace_declaration{ n_, s } @@ -3956,7 +3997,7 @@ namespace_declaration::namespace_declaration(namespace_declaration&& that) noexc #line 652 "reflect.h2" alias_declaration::alias_declaration( - declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : declaration{ n_, s } @@ -3979,7 +4020,7 @@ alias_declaration::alias_declaration(alias_declaration&& that) noexcept #line 671 "reflect.h2" parameter_declaration::parameter_declaration( - parameter_declaration_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4022,7 +4063,7 @@ parameter_declaration::parameter_declaration(parameter_declaration&& that) noexc #line 717 "reflect.h2" template binary_expression::binary_expression( - binary_expression_node* n_, + binary_expression_node* const& n_, cpp2::impl::in s ) : reflection_base>{ n_, s } @@ -4185,7 +4226,7 @@ template binary_expression::binary_expre #line 844 "reflect.h2" expression_list::expression_list( - expression_list_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4226,7 +4267,7 @@ expression_list::expression_list(expression_list&& that) noexcept #line 877 "reflect.h2" prefix_expression::prefix_expression( - prefix_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4286,7 +4327,7 @@ prefix_expression::prefix_expression(prefix_expression&& that) noexcept #line 919 "reflect.h2" postfix_expression::postfix_expression( - postfix_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4388,7 +4429,7 @@ postfix_expression::postfix_expression(postfix_expression&& that) noexcept #line 990 "reflect.h2" template_arg::template_arg( - template_argument* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4423,7 +4464,7 @@ template_arg::template_arg(template_arg&& that) noexcept #line 1016 "reflect.h2" unqualified_id::unqualified_id( - unqualified_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4463,7 +4504,7 @@ unqualified_id::unqualified_id(unqualified_id&& that) noexcept #line 1048 "reflect.h2" qualified_id::qualified_id( - qualified_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4521,7 +4562,7 @@ qualified_id::qualified_id(qualified_id&& that) noexcept #line 1092 "reflect.h2" type_id::type_id( - type_id_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4582,7 +4623,7 @@ type_id::type_id(type_id&& that) noexcept #line 1135 "reflect.h2" primary_expression::primary_expression( - primary_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4637,7 +4678,7 @@ primary_expression::primary_expression(primary_expression&& that) noexcept #line 1174 "reflect.h2" id_expression::id_expression( - id_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4687,7 +4728,7 @@ id_expression::id_expression(id_expression&& that) noexcept #line 1210 "reflect.h2" expression::expression( - expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4760,7 +4801,7 @@ expression::expression(expression&& that) noexcept #line 1261 "reflect.h2" is_as_expression::is_as_expression( - is_as_expression_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4845,7 +4886,7 @@ is_as_expression::is_as_expression(is_as_expression&& that) noexcept #line 1322 "reflect.h2" statement::statement( - statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4909,7 +4950,7 @@ statement::statement(statement&& that) noexcept #line 1364 "reflect.h2" expression_statement::expression_statement( - expression_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4937,7 +4978,7 @@ expression_statement::expression_statement(expression_statement&& that) noexcept #line 1386 "reflect.h2" compound_statement::compound_statement( - compound_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -4982,7 +5023,7 @@ compound_statement::compound_statement(compound_statement&& that) noexcept #line 1425 "reflect.h2" selection_statement::selection_statement( - selection_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -5018,7 +5059,7 @@ selection_statement::selection_statement(selection_statement&& that) noexcept #line 1451 "reflect.h2" return_statement::return_statement( - return_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -5046,7 +5087,7 @@ return_statement::return_statement(return_statement&& that) noexcept #line 1473 "reflect.h2" iteration_statement::iteration_statement( - iteration_statement_node* n_, + cpp2::impl::in n_, cpp2::impl::in s ) : reflection_base{ n_, s } @@ -7900,56 +7941,61 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 4129 "reflect.h2" // TODO: Maybe use variant here. -#line 4132 "reflect.h2" +#line 4133 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(){} -#line 4134 "reflect.h2" - autodiff_declared_variable::autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_member_) +#line 4135 "reflect.h2" + autodiff_declared_variable::autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_active_, cpp2::impl::in is_member_) : name{ name_ } , decl{ decl_ } + , is_active{ is_active_ } , is_member{ is_member_ }{ -#line 4138 "reflect.h2" +#line 4140 "reflect.h2" } -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable const& that) : name{ that.name } , decl{ that.decl } + , is_active{ that.is_active } , is_member{ that.is_member }{} -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" auto autodiff_declared_variable::operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& { name = that.name; decl = that.decl; + is_active = that.is_active; is_member = that.is_member; return *this; } -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable&& that) noexcept : name{ std::move(that).name } , decl{ std::move(that).decl } + , is_active{ std::move(that).is_active } , is_member{ std::move(that).is_member }{} -#line 4140 "reflect.h2" +#line 4142 "reflect.h2" auto autodiff_declared_variable::operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& { name = std::move(that).name; decl = std::move(that).decl; + is_active = std::move(that).is_active; is_member = std::move(that).is_member; return *this; } -#line 4144 "reflect.h2" +#line 4146 "reflect.h2" // namespace + type name -#line 4152 "reflect.h2" +#line 4154 "reflect.h2" autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) : full_name{ full_name_ } , decl{ decl_ }{ -#line 4155 "reflect.h2" +#line 4157 "reflect.h2" } -#line 4157 "reflect.h2" +#line 4159 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 4158 "reflect.h2" +#line 4160 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -7959,11 +8005,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return r; } -#line 4167 "reflect.h2" +#line 4169 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret{ bool found {false}; autodiff_declared_variable r {}; -#line 4168 "reflect.h2" +#line 4170 "reflect.h2" for ( auto const& cur_context : std::ranges::views::reverse(declared_variables_stack) ) { for ( auto const& cur : cur_context ) { if (cur.name == decl_name) { @@ -7988,7 +8034,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , diff_done{ std::move(that).diff_done } , declared_variables_stack{ std::move(that).declared_variables_stack }{} -#line 4185 "reflect.h2" +#line 4187 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -7999,26 +8045,29 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar /* is_member = */ -#line 4200 "reflect.h2" +#line 4202 "reflect.h2" /* is_member = */ -#line 4206 "reflect.h2" +#line 4208 "reflect.h2" /* is_member = */ -#line 4212 "reflect.h2" +#line 4214 "reflect.h2" + /* is_member = */ + +#line 4220 "reflect.h2" /* is_member = */ -#line 4222 "reflect.h2" +#line 4230 "reflect.h2" // Members depending on order -#line 4229 "reflect.h2" +#line 4237 "reflect.h2" autodiff_context::autodiff_context(){} -#line 4230 "reflect.h2" +#line 4238 "reflect.h2" autodiff_context::autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_) : order{ order_ } , reverse{ reverse_ }{ -#line 4234 "reflect.h2" +#line 4242 "reflect.h2" if (1 != order) { if (reverse) { fwd_ad_type = "cpp2::taylor"; @@ -8031,12 +8080,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } -#line 4246 "reflect.h2" - auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_member) & -> void{ - CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_member)); +#line 4254 "reflect.h2" + auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member) & -> void{ + CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_active, is_member)); } -#line 4250 "reflect.h2" +#line 4258 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_variable_active(cpp2::impl::in name) & -> bool{ + return lookup_variable_declaration(name).is_active; + } + +#line 4262 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -8054,20 +8108,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4267 "reflect.h2" +#line 4279 "reflect.h2" [[nodiscard]] auto autodiff_context::is_forward() const& -> decltype(auto) { return !(reverse) || (reverse && order != 1); } -#line 4268 "reflect.h2" +#line 4280 "reflect.h2" [[nodiscard]] auto autodiff_context::is_reverse() const& -> decltype(auto) { return reverse; } -#line 4269 "reflect.h2" +#line 4281 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4271 "reflect.h2" +#line 4283 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4276 "reflect.h2" +#line 4288 "reflect.h2" + [[nodiscard]] auto autodiff_context::is_type_active(cpp2::impl::in type) & -> bool{ + auto decls {lookup_type_declaration(type)}; + auto r {false}; + + if (!(CPP2_UFCS(empty)(decls))) { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(ssize)(decls) == 1) ) { cpp2::cpp2_default.report_violation(""); } + autodiff_activity_check ada {&(*this)}; + CPP2_UFCS(pre_traverse)(ada, CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(decls), 0)); + r = cpp2::move(ada).active; + } + + // TODO: Add template activity lookup. + + if (!(r)) { + // Declaration lookup did not yield an activity: Apply some heuristics. + r = CPP2_UFCS(contains)(type, "double"); + } + + return r; + } + +#line 4309 "reflect.h2" [[nodiscard]] auto autodiff_context::get_fwd_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8086,7 +8162,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", fwd_ad_type); } -#line 4294 "reflect.h2" +#line 4327 "reflect.h2" [[nodiscard]] auto autodiff_context::get_rws_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8105,7 +8181,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", rws_ad_type); } -#line 4312 "reflect.h2" +#line 4345 "reflect.h2" [[nodiscard]] auto autodiff_context::get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style{ // TODO: inspect does not work here: error: error: no matching function for call to ‘is(const cpp2::passing_style&)’ // return inspect p -> passing_style { @@ -8128,16 +8204,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar if (p == passing_style::forward) { return passing_style::inout; } if (p == passing_style::forward_ref) { return passing_style::inout; } -#line 4335 "reflect.h2" +#line 4368 "reflect.h2" CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Do not know how to handle passing style:" + cpp2::to_string(p) + ""); return passing_style::inout; } -#line 4340 "reflect.h2" +#line 4373 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4341 "reflect.h2" +#line 4374 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -8160,10 +8236,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4363 "reflect.h2" +#line 4396 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ if (name == "_") { - return autodiff_declared_variable(name, "_", false); + return autodiff_declared_variable(name, "_", false, false); } for ( auto const& cur_context : std::ranges::views::reverse(declaration_stack) ) { @@ -8178,10 +8254,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return autodiff_declared_variable(); } -#line 4380 "reflect.h2" +#line 4413 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4381 "reflect.h2" +#line 4414 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8191,10 +8267,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4390 "reflect.h2" +#line 4423 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ std::vector r {}; -#line 4391 "reflect.h2" +#line 4424 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); @@ -8204,10 +8280,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4400 "reflect.h2" +#line 4433 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4401 "reflect.h2" +#line 4434 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8217,12 +8293,12 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4410 "reflect.h2" +#line 4443 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4411 "reflect.h2" +#line 4444 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -8244,7 +8320,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; } -#line 4432 "reflect.h2" +#line 4465 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -8253,7 +8329,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4440 "reflect.h2" +#line 4473 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -8274,7 +8350,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4460 "reflect.h2" +#line 4493 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -8285,18 +8361,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4470 "reflect.h2" +#line 4503 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4475 "reflect.h2" +#line 4508 "reflect.h2" auto autodiff_context::leave_function() & -> void{ CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4479 "reflect.h2" +#line 4512 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -8310,7 +8386,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4492 "reflect.h2" +#line 4525 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -8326,38 +8402,38 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4507 "reflect.h2" +#line 4540 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4521 "reflect.h2" - autodiff_diff_code::autodiff_diff_code(autodiff_context* ctx_) +#line 4554 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(cpp2::impl::in ctx_) : ctx{ ctx_ }{ -#line 4523 "reflect.h2" +#line 4556 "reflect.h2" } -#line 4521 "reflect.h2" - auto autodiff_diff_code::operator=(autodiff_context* ctx_) -> autodiff_diff_code& { +#line 4554 "reflect.h2" + auto autodiff_diff_code::operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& { ctx = ctx_; fwd = ""; rws_primal = ""; rws_backprop = ""; return *this; -#line 4523 "reflect.h2" +#line 4556 "reflect.h2" } -#line 4525 "reflect.h2" +#line 4558 "reflect.h2" auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} -#line 4526 "reflect.h2" +#line 4559 "reflect.h2" auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} -#line 4527 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop += v; }} -#line 4529 "reflect.h2" +#line 4562 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ fwd = ""; rws_primal = ""; @@ -8365,7 +8441,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4536 "reflect.h2" +#line 4569 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; @@ -8373,66 +8449,156 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4539 "reflect.h2" +#line 4572 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4542 "reflect.h2" +#line 4575 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4547 "reflect.h2" +#line 4580 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4552 "reflect.h2" +#line 4585 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4557 "reflect.h2" +#line 4590 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4567 "reflect.h2" - autodiff_handler_base::autodiff_handler_base(autodiff_context* ctx_) +#line 4601 "reflect.h2" + autodiff_activity_check::autodiff_activity_check(cpp2::impl::in ctx_) + : simple_traverser{ } + , ctx{ ctx_ }{ + +#line 4603 "reflect.h2" + } + +#line 4605 "reflect.h2" + auto autodiff_activity_check::traverse(cpp2::impl::in o) -> void{ + + auto type {o.type()}; + + if ("_" == type) { + if (CPP2_UFCS(has_initializer)(o)) { + pre_traverse(CPP2_UFCS(get_initializer)(o)); + } + else { + // Assume active + active = true; + } + } + else { + active |= CPP2_UFCS(is_type_active)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(type)); + } + } + +#line 4623 "reflect.h2" + auto autodiff_activity_check::traverse(cpp2::impl::in primary) -> void + { + if (CPP2_UFCS(is_identifier)(primary)) { + active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(primary)); + } + else {if (CPP2_UFCS(is_expression_list)(primary)) { + for ( auto const& cur : CPP2_UFCS(get_expressions)(CPP2_UFCS(as_expression_list)(primary)) ) { + pre_traverse(cur); + } + } + else {if (CPP2_UFCS(is_literal)(primary)) { + // TODO: Improve check + if (CPP2_UFCS(contains)(CPP2_UFCS(to_string)(primary), ".")) { + active = true; + } + } + else {if (CPP2_UFCS(is_declaration)(primary)) { + pre_traverse(CPP2_UFCS(as_declaration)(primary)); + } + else { + CPP2_UFCS(error)(primary, "AD: Unknown primary expression kind: " + cpp2::to_string(CPP2_UFCS(to_string)(primary)) + ""); + }}}} + } + +#line 4647 "reflect.h2" + auto autodiff_activity_check::traverse(cpp2::impl::in postfix) -> void + { + auto terms {CPP2_UFCS(get_terms)(postfix)}; + + auto is_func {false}; +{ +auto i{0}; + +#line 4654 "reflect.h2" + for ( auto const& term : terms ) { do { + if (CPP2_UFCS(get_op)(term) == ".") { + continue; + } + if (CPP2_UFCS(get_op)(term) == "(" && i + 1 == CPP2_UFCS(ssize)(terms)) {// Function operator has to be the last + is_func = true; + continue; + } + else { + CPP2_UFCS(error)(postfix, "AD: Unknown operator for postfix expression. op: " + cpp2::to_string(CPP2_UFCS(get_op)(term)) + " expr: " + cpp2::to_string(postfix) + ""); + } + } while (false); i += 1; } +} + + // TODO: Really check for members +#line 4668 "reflect.h2" + if (CPP2_UFCS(ssize)(terms) != 1) { + active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))); + } + + if (cpp2::move(is_func)) { + // Check arguments of function + for ( auto const& cur : CPP2_UFCS(get_expressions)(CPP2_UFCS(get_expression_list)(CPP2_UFCS(back)(cpp2::move(terms)))) ) { + pre_traverse(cur); + } + } + } + +#line 4686 "reflect.h2" + autodiff_handler_base::autodiff_handler_base(cpp2::impl::in ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4570 "reflect.h2" +#line 4689 "reflect.h2" } -#line 4567 "reflect.h2" - auto autodiff_handler_base::operator=(autodiff_context* ctx_) -> autodiff_handler_base& { +#line 4686 "reflect.h2" + auto autodiff_handler_base::operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4570 "reflect.h2" +#line 4689 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4573 "reflect.h2" +#line 4692 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff.fwd += o.diff.fwd; diff.rws_primal += o.diff.rws_primal; diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4590 "reflect.h2" - autodiff_expression_handler::autodiff_expression_handler(autodiff_context* ctx_) +#line 4709 "reflect.h2" + autodiff_expression_handler::autodiff_expression_handler(cpp2::impl::in ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4592 "reflect.h2" +#line 4711 "reflect.h2" } -#line 4594 "reflect.h2" +#line 4713 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8442,7 +8608,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4603 "reflect.h2" +#line 4722 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ auto r {rhs_b}; r = string_util::replace_all(r, "_r_", lhs); @@ -8452,7 +8618,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4612 "reflect.h2" +#line 4731 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8463,14 +8629,14 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4622 "reflect.h2" +#line 4741 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4624 "reflect.h2" +#line 4743 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4628 "reflect.h2" +#line 4747 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8481,24 +8647,25 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4638 "reflect.h2" +#line 4757 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4640 "reflect.h2" +#line 4759 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4642 "reflect.h2" +#line 4761 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } - autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_) -requires (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) - : primal{ CPP2_FORWARD(primal_) } - , fwd{ CPP2_FORWARD(fwd_) } - , rws{ CPP2_FORWARD(rws_) }{} + autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_, auto&& active_) +requires (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) + : primal{ CPP2_FORWARD(primal_) } + , fwd{ CPP2_FORWARD(fwd_) } + , rws{ CPP2_FORWARD(rws_) } + , active{ CPP2_FORWARD(active_) }{} autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} -#line 4653 "reflect.h2" +#line 4773 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8508,7 +8675,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4662 "reflect.h2" +#line 4782 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8516,53 +8683,61 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} auto rws {primal + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; auto decl {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), primal)}; - if (cpp2::move(decl).is_member) { + if (decl.is_member) { fwd = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "." + fwd; rws = "this" + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "." + rws; } - return { cpp2::move(primal), cpp2::move(fwd), cpp2::move(rws) }; + + if (cpp2::move(decl).is_active) { + return { cpp2::move(primal), cpp2::move(fwd), cpp2::move(rws), true }; + } + else { + return { cpp2::move(primal), "", "", false }; + } + } else {if (CPP2_UFCS(is_expression_list)(term)) { auto exprs {term.as_expression_list().get_expressions()}; if (CPP2_UFCS(ssize)(exprs) != 1) { CPP2_UFCS(error)(term, "Can not handle multiple expressions. (term.to_string())"); - return { "error", "", "" }; + return { "error", "", "", false }; } auto expr {CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(exprs), 0)}; auto bin_expr {expr.as_assignment_expression()}; if (CPP2_UFCS(terms_size)(bin_expr) != 0) { CPP2_UFCS(error)(term, "Can not handle assign expr inside of expression. " + cpp2::to_string(CPP2_UFCS(to_string)(cpp2::move(expr))) + ""); - return { "error", "", "" }; + return { "error", "", "", false }; } - autodiff_expression_handler ad {ctx}; - ad.pre_traverse(CPP2_UFCS(get_term)(CPP2_UFCS(front)(CPP2_UFCS(get_terms)(cpp2::move(bin_expr))))); - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression - append(cpp2::move(ad)); - - primal_fwd_rws_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) - static_cast(cpp2::move(t)); - return r; + return handle_expression_term(CPP2_UFCS(get_term)(CPP2_UFCS(front)(CPP2_UFCS(get_terms)(cpp2::move(bin_expr))))); } else { // Nothing special. A regular expression. auto expr {term}; - autodiff_expression_handler ad {ctx}; - ad.pre_traverse(cpp2::move(expr)); - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression - append(cpp2::move(ad)); + autodiff_activity_check ada {ctx}; + CPP2_UFCS(pre_traverse)(ada, expr); - primal_fwd_rws_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) - static_cast(cpp2::move(t)); - return r; + if (cpp2::move(ada).active) { + + autodiff_expression_handler ad {ctx}; + ad.pre_traverse(cpp2::move(expr)); + auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; + CPP2_UFCS(gen_declaration)(ad, t, "double");// TODO: get type of expression + append(cpp2::move(ad)); + + primal_fwd_rws_name r {t, t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, true}; // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + static_cast(cpp2::move(t)); + return r; + } + else { + return { CPP2_UFCS(to_string)(cpp2::move(expr)), "", "", false }; + } }} } -#line 4715 "reflect.h2" +#line 4843 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8570,7 +8745,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4721 "reflect.h2" +#line 4849 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8584,7 +8759,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4733 "reflect.h2" +#line 4861 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8607,7 +8782,7 @@ auto i{0}; { auto i{0}; -#line 4754 "reflect.h2" +#line 4882 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8632,7 +8807,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4777 "reflect.h2" +#line 4905 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8658,7 +8833,12 @@ auto i{0}; diff += "" + cpp2::to_string(cpp2::move(object_d)) + ", "; } for ( auto const& arg : cpp2::move(args) ) { - diff += "" + cpp2::to_string(arg.primal) + ", " + cpp2::to_string(arg.fwd) + ","; + if (arg.active) { + diff += "" + cpp2::to_string(arg.primal) + ", " + cpp2::to_string(arg.fwd) + ", "; + } + else { + diff += "" + cpp2::to_string(arg.primal) + ", "; + } } diff += ");\n"; @@ -8715,7 +8895,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4859 "reflect.h2" +#line 4992 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8738,7 +8918,7 @@ auto i{0}; { auto i{1}; -#line 4880 "reflect.h2" +#line 5013 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8748,69 +8928,69 @@ auto i{1}; } } -#line 4888 "reflect.h2" +#line 5021 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 4894 "reflect.h2" +#line 5027 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 4898 "reflect.h2" +#line 5031 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 4902 "reflect.h2" +#line 5035 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 4906 "reflect.h2" +#line 5039 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 4910 "reflect.h2" +#line 5043 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 4914 "reflect.h2" +#line 5047 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 4918 "reflect.h2" +#line 5051 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 4922 "reflect.h2" +#line 5055 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 4926 "reflect.h2" +#line 5059 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 4930 "reflect.h2" +#line 5063 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 4934 "reflect.h2" +#line 5067 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 4938 "reflect.h2" +#line 5071 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -8828,8 +9008,10 @@ auto i{1}; } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; - fwd += var.fwd; - rws += "" + cpp2::to_string(var.rws) + " " + cpp2::to_string(op) + "= _rb_;\n"; + if (var.active) { + fwd += var.fwd; + rws += "" + cpp2::to_string(var.rws) + " " + cpp2::to_string(op) + "= _rb_;\n"; + } primal += cpp2::move(var).primal; first = false; @@ -8840,21 +9022,15 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 4967 "reflect.h2" +#line 5102 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; - auto var {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; - auto arg_a {var.primal}; - auto arg_a_d {var.fwd}; - auto arg_a_b {var.rws}; + auto var_a {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(terms, 0)))}; int i {1}; for( ; cpp2::impl::cmp_less(i,CPP2_UFCS(ssize)(terms)); i += 1 ) { - var = handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i))); - auto arg_b {var.primal}; - auto arg_b_d {var.fwd}; - auto arg_b_b {var.rws}; + auto var_b {handle_expression_term(CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; auto op {CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(CPP2_ASSERT_IN_BOUNDS(terms, i)))}; @@ -8864,35 +9040,60 @@ auto i{1}; if ("*" == op) { if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - fwd = "" + cpp2::to_string(arg_a_d) + "..mul(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; - rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " += " + cpp2::to_string(arg_a_d) + "..mul(_rb_, " + cpp2::to_string(arg_a) + ", _r_);\n" - "" + cpp2::to_string(arg_a_b) + " += " + cpp2::to_string(cpp2::move(arg_b_d)) + "..mul(_rb_, " + cpp2::to_string(arg_b) + ", _r_);"; + // TODO: Add taylor overloads + fwd = "" + cpp2::to_string(var_a.fwd) + "..mul(" + cpp2::to_string(var_b.fwd) + ", " + cpp2::to_string(var_a.primal) + ", " + cpp2::to_string(var_b.primal) + ")"; + if (var_a.active) { + //fwd += "(var_b.primal)$ * (var_a.fwd)$"; + rws += "" + cpp2::to_string(var_a.rws) + " += " + cpp2::to_string(var_b.fwd) + "..mul(_rb_, " + cpp2::to_string(var_b.primal) + ", _r_);\n"; + } + if (var_b.active) { + if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } + //fwd += "(var_a.primal)$ * (var_b.fwd)$"; + rws = "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.fwd) + "..mul(_rb_, " + cpp2::to_string(var_a.primal) + ", _r_);\n"; + } } else { - fwd = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " + " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_a_d) + ""; - rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " += " + cpp2::to_string(arg_a) + " * _rb_;\n" - "" + cpp2::to_string(arg_a_b) + " += " + cpp2::to_string(arg_b) + " * _rb_;"; + if (var_a.active) { + fwd += "" + cpp2::to_string(var_b.primal) + " * " + cpp2::to_string(var_a.fwd) + ""; + rws += "" + cpp2::to_string(var_a.rws) + " += " + cpp2::to_string(var_b.primal) + " * _rb_;\n"; + } + if (var_b.active) { + if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } + fwd += "" + cpp2::to_string(var_a.primal) + " * " + cpp2::to_string(var_b.fwd) + ""; + rws = "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.primal) + " * _rb_;\n"; + } } - primal = "" + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b)) + ""; + primal = "" + cpp2::to_string(var_a.primal) + " * " + cpp2::to_string(var_b.primal) + ""; } else {if ("/" == op) { if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - fwd = "" + cpp2::to_string(arg_a_d) + ".div(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_a) + ", " + cpp2::to_string(arg_b) + ")"; - rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " -= " + cpp2::to_string(arg_a_d) + ".mul(_rb_, " + cpp2::to_string(arg_a) + ", _r_).div(" + cpp2::to_string(arg_b_d) + ".mul(" + cpp2::to_string(arg_b_d) + ", " + cpp2::to_string(arg_b) + ", " + cpp2::to_string(arg_b) + "), " + cpp2::to_string(arg_a) + " * _r_, " + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ");\n" - "" + cpp2::to_string(arg_a_b) + " += _rb_.div(" + cpp2::to_string(arg_b_d) + ", _r_, " + cpp2::to_string(arg_b) + ");"; + // TODO: Add taylor overloads + fwd = "" + cpp2::to_string(var_a.fwd) + ".div(" + cpp2::to_string(var_b.fwd) + ", " + cpp2::to_string(var_a.primal) + ", " + cpp2::to_string(var_b.primal) + ")"; + if (var_a.active) { + rws += "" + cpp2::to_string(var_a.rws) + " += _rb_.div(" + cpp2::to_string(var_b.fwd) + ", _r_, " + cpp2::to_string(var_b.primal) + ");\n"; + } + if (var_b.active) { + rws += "" + cpp2::to_string(var_b.rws) + " -= " + cpp2::to_string(var_a.fwd) + ".mul(_rb_, " + cpp2::to_string(var_a.primal) + ", _r_).div(" + cpp2::to_string(var_b.fwd) + ".mul(" + cpp2::to_string(var_b.fwd) + ", " + cpp2::to_string(var_b.primal) + ", " + cpp2::to_string(var_b.primal) + "), " + cpp2::to_string(var_a.primal) + " * _r_, " + cpp2::to_string(var_b.primal) + " * " + cpp2::to_string(var_b.primal) + ");\n"; + } } else { - fwd = "" + cpp2::to_string(arg_a_d) + " / " + cpp2::to_string(arg_b) + " - " + cpp2::to_string(arg_a) + " * " + cpp2::to_string(cpp2::move(arg_b_d)) + " / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ")"; - rws = "" + cpp2::to_string(cpp2::move(arg_b_b)) + " -= " + cpp2::to_string(arg_a) + " * _rb_ / (" + cpp2::to_string(arg_b) + " * " + cpp2::to_string(arg_b) + ");\n" - "" + cpp2::to_string(arg_a_b) + " += _rb_ / " + cpp2::to_string(arg_b) + ";"; + if (var_a.active) { + fwd += "" + cpp2::to_string(var_a.fwd) + " / " + cpp2::to_string(var_b.primal) + ""; + rws = "" + cpp2::to_string(var_a.rws) + " += _rb_ / " + cpp2::to_string(var_b.primal) + ";\n"; + } + if (var_b.active) { + if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } + fwd += "-" + cpp2::to_string(var_a.primal) + " * " + cpp2::to_string(var_b.fwd) + " / (" + cpp2::to_string(var_b.primal) + " * " + cpp2::to_string(var_b.primal) + ")"; + rws += "" + cpp2::to_string(var_b.rws) + " -= " + cpp2::to_string(var_a.primal) + " * _rb_ / (" + cpp2::to_string(var_b.primal) + " * " + cpp2::to_string(var_b.primal) + ");\n"; + } } - primal = "" + cpp2::to_string(arg_a) + " / " + cpp2::to_string(cpp2::move(arg_b)) + ""; + primal = "" + cpp2::to_string(var_a.primal) + " / " + cpp2::to_string(var_b.primal) + ""; } else { CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5019 "reflect.h2" +#line 5173 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -8900,24 +9101,21 @@ auto i{1}; } else { // Temporary - auto t {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx)))}; - auto t_d {t + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; - auto t_b {t + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; - gen_declaration(t, t_d, t_b, cpp2::move(primal), cpp2::move(fwd), cpp2::move(rws), "", "", ""); - - arg_a = cpp2::move(t); - arg_a_d = cpp2::move(t_d); - arg_a_b = cpp2::move(t_b); + var_a.primal = CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx))); + var_a.fwd = var_a.primal + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; + var_a.rws = var_a.primal + (*cpp2::impl::assert_not_null(ctx)).rws_suffix; + var_a.active = var_a.active | cpp2::move(var_b).active; + gen_declaration(var_a.primal, var_a.fwd, var_a.rws, primal, cpp2::move(fwd), cpp2::move(rws), "", "", ""); } } } -#line 5038 "reflect.h2" +#line 5189 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5042 "reflect.h2" +#line 5193 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -8934,7 +9132,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5058 "reflect.h2" +#line 5209 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8943,7 +9141,7 @@ auto i{1}; { auto i{0}; -#line 5065 "reflect.h2" +#line 5216 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8958,7 +9156,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5078 "reflect.h2" +#line 5229 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -8979,7 +9177,7 @@ auto i{0}; } } -#line 5098 "reflect.h2" +#line 5249 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9016,70 +9214,92 @@ auto i{0}; }}}} } -#line 5143 "reflect.h2" - autodiff_stmt_handler::autodiff_stmt_handler(autodiff_context* ctx_, cpp2::impl::in mf_) +#line 5294 "reflect.h2" + autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5146 "reflect.h2" +#line 5297 "reflect.h2" } -#line 5148 "reflect.h2" +#line 5299 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5153 "reflect.h2" +#line 5304 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5158 "reflect.h2" +#line 5309 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; - auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + auto active {false}; + if ("_" != type) { + active = CPP2_UFCS(is_type_active)((*cpp2::impl::assert_not_null(ctx)), type); + } + else { + if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(has_initializer)(o)) ) { cpp2::cpp2_default.report_violation(""); } - std::string prim_init {""}; - std::string fwd_init {""}; + autodiff_activity_check ada {ctx}; + CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_initializer)(o)); + active = cpp2::move(ada).active; + } - if (CPP2_UFCS(has_initializer)(o)) { - autodiff_expression_handler ad {ctx}; - CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(o)); - append(ad); + if (active) { + + auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + + std::string prim_init {""}; + std::string fwd_init {""}; + + if (CPP2_UFCS(has_initializer)(o)) { + autodiff_expression_handler ad {ctx}; + CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(o)); + append(ad); - prim_init = " = " + ad.primal_expr; - fwd_init = " = " + ad.fwd_expr; + prim_init = " = " + ad.primal_expr; + fwd_init = " = " + ad.fwd_expr; - if (type == "_" && cpp2::move(ad).fwd_expr == "()") { - // Special handling for auto initialization from a literal. - fwd_init = " = " + CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; + if (type == "_" && cpp2::move(ad).fwd_expr == "()") { + // Special handling for auto initialization from a literal. + fwd_init = " = " + CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; + } + } + diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; + diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; + } + else { + diff += "" + cpp2::to_string(lhs) + ": " + cpp2::to_string(type) + ""; + if (CPP2_UFCS(has_initializer)(o)) { + diff += " = " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_initializer)(o))) + ""; } + diff += ";\n"; } - diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; - diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; - CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type)); + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5187 "reflect.h2" +#line 5360 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5192 "reflect.h2" +#line 5365 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5197 "reflect.h2" +#line 5370 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5202 "reflect.h2" +#line 5375 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -9087,7 +9307,7 @@ auto i{0}; diff += "}\n"; } -#line 5210 "reflect.h2" +#line 5383 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9104,7 +9324,7 @@ auto i{0}; } } -#line 5227 "reflect.h2" +#line 5400 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -9147,14 +9367,14 @@ auto i{0}; diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; - CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "");// TODO: Handle loop/compound context variable declarations. + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "", true);// TODO: Handle loop/compound context variable declarations. pre_traverse(CPP2_UFCS(get_for_body)(stmt)); diff += "}\n"; }} } -#line 5277 "reflect.h2" +#line 5450 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9166,12 +9386,12 @@ auto i{0}; } } -#line 5288 "reflect.h2" +#line 5461 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5292 "reflect.h2" +#line 5465 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_expression_handler h_lhs {ctx}; CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9185,73 +9405,73 @@ auto i{0}; append(cpp2::move(h)); } -#line 5305 "reflect.h2" +#line 5478 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5309 "reflect.h2" +#line 5482 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5313 "reflect.h2" +#line 5486 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5317 "reflect.h2" +#line 5490 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5321 "reflect.h2" +#line 5494 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5325 "reflect.h2" +#line 5498 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5329 "reflect.h2" +#line 5502 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5333 "reflect.h2" +#line 5506 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5337 "reflect.h2" +#line 5510 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5341 "reflect.h2" +#line 5514 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5345 "reflect.h2" +#line 5518 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5349 "reflect.h2" +#line 5522 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5353 "reflect.h2" +#line 5526 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5358 "reflect.h2" +#line 5531 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9260,7 +9480,7 @@ auto i{0}; { auto i{0}; -#line 5365 "reflect.h2" +#line 5538 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9275,7 +9495,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5378 "reflect.h2" +#line 5551 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9288,30 +9508,32 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5390 "reflect.h2" +#line 5563 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5407 "reflect.h2" - autodiff_declaration_handler::autodiff_declaration_handler(autodiff_context* ctx_, cpp2::impl::in decl_) +#line 5580 "reflect.h2" + autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5410 "reflect.h2" +#line 5583 "reflect.h2" } -#line 5412 "reflect.h2" +#line 5585 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5417 "reflect.h2" +#line 5590 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); + // TODO: Add activity for member functions + CPP2_UFCS(add_forward)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": ("); CPP2_UFCS(add_reverse_primal)(diff, " " + cpp2::to_string(CPP2_UFCS(name)(f)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ": ("); @@ -9339,17 +9561,26 @@ auto i{0}; } else { auto type {CPP2_UFCS(get_declaration)(param).type()}; - CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); - CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); - CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); - if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { - CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + autodiff_activity_check ada {ctx}; + CPP2_UFCS(pre_traverse)(ada, param); + + if (ada.active) { + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + } + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); + } + else { + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + ", "); } - CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(rws_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + ", "); -#line 5457 "reflect.h2" - CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type)); + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type), cpp2::move(ada).active); } } @@ -9413,7 +9644,7 @@ auto i{0}; CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); } - CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + ""); + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(cpp2::move(name)) + "", "" + cpp2::to_string(cpp2::move(type)) + "", true);// TODO_a: Add acitivty check } } @@ -9427,10 +9658,10 @@ auto i{0}; return ; } -#line 5536 "reflect.h2" +#line 5720 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5539 "reflect.h2" +#line 5723 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9455,7 +9686,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5564 "reflect.h2" +#line 5748 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9480,10 +9711,10 @@ auto i{0}; } diff = ""; - CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true); + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5592 "reflect.h2" +#line 5776 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9507,17 +9738,17 @@ auto i{0}; } } -#line 5616 "reflect.h2" +#line 5800 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5621 "reflect.h2" +#line 5805 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5627 "reflect.h2" +#line 5811 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9693,7 +9924,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5712 "reflect.h2" +#line 5896 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9709,11 +9940,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5728 "reflect.h2" +#line 5912 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5732 "reflect.h2" +#line 5916 "reflect.h2" // mod: i // mod: m // mod: s @@ -9721,116 +9952,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5741 "reflect.h2" +#line 5925 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5750 "reflect.h2" +#line 5934 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5752 "reflect.h2" +#line 5936 "reflect.h2" } -#line 5754 "reflect.h2" +#line 5938 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5756 "reflect.h2" +#line 5940 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5762 "reflect.h2" +#line 5946 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5763 "reflect.h2" +#line 5947 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5764 "reflect.h2" +#line 5948 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5779 "reflect.h2" +#line 5963 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5782 "reflect.h2" +#line 5966 "reflect.h2" } -#line 5784 "reflect.h2" +#line 5968 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5788 "reflect.h2" +#line 5972 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5800 "reflect.h2" +#line 5984 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5803 "reflect.h2" +#line 5987 "reflect.h2" } -#line 5805 "reflect.h2" +#line 5989 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5809 "reflect.h2" +#line 5993 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 5819 "reflect.h2" +#line 6003 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 5821 "reflect.h2" +#line 6005 "reflect.h2" } -#line 5823 "reflect.h2" +#line 6007 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 5827 "reflect.h2" +#line 6011 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 5839 "reflect.h2" +#line 6023 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 5842 "reflect.h2" +#line 6026 "reflect.h2" } -#line 5844 "reflect.h2" +#line 6028 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 5850 "reflect.h2" +#line 6034 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 5856 "reflect.h2" +#line 6040 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -9839,7 +10070,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 5864 "reflect.h2" +#line 6048 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -9855,7 +10086,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 5892 "reflect.h2" +#line 6076 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -9863,14 +10094,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 5900 "reflect.h2" +#line 6084 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 5907 "reflect.h2" +#line 6091 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -9882,15 +10113,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 5919 "reflect.h2" +#line 6103 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 5924 "reflect.h2" +#line 6108 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 5928 "reflect.h2" +#line 6112 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -9911,7 +10142,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 5954 "reflect.h2" +#line 6138 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -9920,20 +10151,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 5963 "reflect.h2" +#line 6147 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 5969 "reflect.h2" +#line 6153 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 5976 "reflect.h2" +#line 6160 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -9948,16 +10179,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6006 "reflect.h2" +#line 6190 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6010 "reflect.h2" +#line 6194 "reflect.h2" } -#line 6016 "reflect.h2" +#line 6200 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -9967,7 +10198,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6026 "reflect.h2" +#line 6210 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -9975,17 +10206,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6033 "reflect.h2" +#line 6217 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6037 "reflect.h2" +#line 6221 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6044 "reflect.h2" +#line 6228 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -9995,7 +10226,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6053 "reflect.h2" +#line 6237 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10003,24 +10234,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6060 "reflect.h2" +#line 6244 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6068 "reflect.h2" +#line 6252 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6072 "reflect.h2" +#line 6256 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6076 "reflect.h2" +#line 6260 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10032,22 +10263,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6087 "reflect.h2" +#line 6271 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6093 "reflect.h2" +#line 6277 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6097 "reflect.h2" +#line 6281 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6101 "reflect.h2" +#line 6285 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10055,7 +10286,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6108 "reflect.h2" +#line 6292 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10067,10 +10298,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6121 "reflect.h2" +#line 6305 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6124 "reflect.h2" +#line 6308 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10110,7 +10341,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6164 "reflect.h2" +#line 6348 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10122,14 +10353,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6175 "reflect.h2" +#line 6359 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6176 "reflect.h2" +#line 6360 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6177 "reflect.h2" +#line 6361 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6179 "reflect.h2" +#line 6363 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10139,10 +10370,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6188 "reflect.h2" +#line 6372 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6190 "reflect.h2" +#line 6374 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10164,14 +10395,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6211 "reflect.h2" +#line 6395 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6212 "reflect.h2" +#line 6396 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6213 "reflect.h2" +#line 6397 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6215 "reflect.h2" +#line 6399 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10185,7 +10416,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6228 "reflect.h2" +#line 6412 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10207,7 +10438,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6249 "reflect.h2" +#line 6433 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10218,12 +10449,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6259 "reflect.h2" +#line 6443 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6260 "reflect.h2" +#line 6444 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6265 "reflect.h2" +#line 6449 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10278,7 +10509,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6319 "reflect.h2" +#line 6503 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10318,7 +10549,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6358 "reflect.h2" +#line 6542 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10334,21 +10565,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6375 "reflect.h2" +#line 6559 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6376 "reflect.h2" +#line 6560 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6377 "reflect.h2" +#line 6561 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6379 "reflect.h2" +#line 6563 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6394 "reflect.h2" +#line 6578 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10356,7 +10587,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6401 "reflect.h2" +#line 6585 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10366,22 +10597,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6419 "reflect.h2" +#line 6603 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6424 "reflect.h2" +#line 6608 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6430 "reflect.h2" +#line 6614 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6436 "reflect.h2" +#line 6620 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10390,7 +10621,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6444 "reflect.h2" +#line 6628 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10402,7 +10633,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6455 "reflect.h2" +#line 6639 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10410,7 +10641,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6462 "reflect.h2" +#line 6646 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10431,7 +10662,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6483 "reflect.h2" +#line 6667 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10441,7 +10672,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6493 "reflect.h2" +#line 6677 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10464,33 +10695,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6517 "reflect.h2" +#line 6701 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6523 "reflect.h2" +#line 6707 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6527 "reflect.h2" +#line 6711 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6533 "reflect.h2" +#line 6717 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6541 "reflect.h2" +#line 6725 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10499,7 +10730,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6549 "reflect.h2" +#line 6733 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10508,22 +10739,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6559 "reflect.h2" +#line 6743 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6563 "reflect.h2" +#line 6747 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6567 "reflect.h2" +#line 6751 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6571 "reflect.h2" +#line 6755 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10547,18 +10778,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6596 "reflect.h2" +#line 6780 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6611 "reflect.h2" +#line 6795 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6613 "reflect.h2" +#line 6797 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10569,15 +10800,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6628 "reflect.h2" +#line 6812 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6631 "reflect.h2" +#line 6815 "reflect.h2" } -#line 6633 "reflect.h2" +#line 6817 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10595,7 +10826,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6650 "reflect.h2" +#line 6834 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10603,7 +10834,7 @@ generation_function_context::generation_function_context(){} } } -#line 6657 "reflect.h2" +#line 6841 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10617,7 +10848,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6670 "reflect.h2" +#line 6854 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10633,14 +10864,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6691 "reflect.h2" +#line 6875 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6693 "reflect.h2" +#line 6877 "reflect.h2" } -#line 6695 "reflect.h2" +#line 6879 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10649,11 +10880,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6710 "reflect.h2" +#line 6894 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6712 "reflect.h2" +#line 6896 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10661,7 +10892,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6719 "reflect.h2" +#line 6903 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10670,37 +10901,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6727 "reflect.h2" +#line 6911 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6741 "reflect.h2" +#line 6925 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6745 "reflect.h2" +#line 6929 "reflect.h2" } -#line 6747 "reflect.h2" +#line 6931 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6751 "reflect.h2" +#line 6935 "reflect.h2" } -#line 6753 "reflect.h2" +#line 6937 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6757 "reflect.h2" +#line 6941 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10709,14 +10940,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6763 "reflect.h2" +#line 6947 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6768 "reflect.h2" +#line 6952 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10729,7 +10960,7 @@ size_t i{0}; } } -#line 6780 "reflect.h2" +#line 6964 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10751,7 +10982,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6801 "reflect.h2" +#line 6985 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10770,7 +11001,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6819 "reflect.h2" +#line 7003 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -10786,14 +11017,14 @@ size_t i{0}; return cpp2::move(str); } -#line 6834 "reflect.h2" +#line 7018 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 6840 "reflect.h2" +#line 7024 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -10801,19 +11032,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 6857 "reflect.h2" +#line 7041 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 6858 "reflect.h2" +#line 7042 "reflect.h2" { -#line 6863 "reflect.h2" +#line 7047 "reflect.h2" } -#line 6866 "reflect.h2" +#line 7050 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -10939,7 +11170,7 @@ size_t i{0}; ); } -#line 6991 "reflect.h2" +#line 7175 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -10949,13 +11180,13 @@ size_t i{0}; ); } -#line 7000 "reflect.h2" +#line 7184 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7005 "reflect.h2" +#line 7189 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -10966,12 +11197,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7017 "reflect.h2" +#line 7201 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7022 "reflect.h2" +#line 7206 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11005,7 +11236,7 @@ size_t i{0}; } -#line 7058 "reflect.h2" +#line 7242 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11014,19 +11245,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7081 "reflect.h2" +#line 7265 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7082 "reflect.h2" +#line 7266 "reflect.h2" { -#line 7087 "reflect.h2" +#line 7271 "reflect.h2" } -#line 7089 "reflect.h2" +#line 7273 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11128,19 +11359,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7190 "reflect.h2" +#line 7374 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7194 "reflect.h2" +#line 7378 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7218 "reflect.h2" +#line 7402 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11159,7 +11390,7 @@ size_t i{0}; return r; } -#line 7236 "reflect.h2" +#line 7420 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11174,7 +11405,7 @@ size_t i{0}; return r; } -#line 7250 "reflect.h2" +#line 7434 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11334,7 +11565,7 @@ size_t i{0}; } } -#line 7409 "reflect.h2" +#line 7593 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11343,7 +11574,7 @@ size_t i{0}; return r; } -#line 7417 "reflect.h2" +#line 7601 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11362,7 +11593,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7435 "reflect.h2" +#line 7619 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11394,7 +11625,7 @@ size_t i{0}; } } -#line 7466 "reflect.h2" +#line 7650 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11405,7 +11636,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7478 "reflect.h2" +#line 7662 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11444,7 +11675,7 @@ size_t i{0}; return r; } -#line 7519 "reflect.h2" +#line 7703 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11462,7 +11693,7 @@ size_t i{0}; }} } -#line 7539 "reflect.h2" +#line 7723 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11476,16 +11707,16 @@ size_t i{0}; } } -#line 7565 "reflect.h2" +#line 7749 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7568 "reflect.h2" +#line 7752 "reflect.h2" } -#line 7570 "reflect.h2" +#line 7754 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11497,7 +11728,7 @@ size_t i{0}; } } -#line 7581 "reflect.h2" +#line 7765 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11505,14 +11736,14 @@ size_t i{0}; return r; } -#line 7588 "reflect.h2" +#line 7772 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7596 "reflect.h2" +#line 7780 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11538,7 +11769,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7624 "reflect.h2" +#line 7808 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11564,11 +11795,11 @@ size_t i{0}; return r; } -#line 7661 "reflect.h2" +#line 7845 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7663 "reflect.h2" +#line 7847 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11642,7 +11873,7 @@ size_t i{0}; return nullptr; } -#line 7736 "reflect.h2" +#line 7920 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11655,7 +11886,7 @@ size_t i{0}; }} } -#line 7748 "reflect.h2" +#line 7932 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11669,7 +11900,7 @@ size_t i{0}; }} } -#line 7761 "reflect.h2" +#line 7945 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11689,7 +11920,7 @@ size_t i{0}; return r; } -#line 7780 "reflect.h2" +#line 7964 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11700,7 +11931,7 @@ size_t i{0}; return r; } -#line 7790 "reflect.h2" +#line 7974 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11712,14 +11943,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7801 "reflect.h2" +#line 7985 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7813 "reflect.h2" +#line 7997 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11743,7 +11974,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 7837 "reflect.h2" +#line 8021 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11753,7 +11984,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 7849 "reflect.h2" +#line 8033 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11769,7 +12000,7 @@ size_t i{0}; } } -#line 7869 "reflect.h2" +#line 8053 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11787,15 +12018,15 @@ size_t i{0}; }} } -#line 7905 "reflect.h2" +#line 8089 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 7908 "reflect.h2" +#line 8092 "reflect.h2" } -#line 7910 "reflect.h2" +#line 8094 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -11831,7 +12062,7 @@ size_t i{0}; return source; } -#line 7945 "reflect.h2" +#line 8129 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -11847,7 +12078,7 @@ size_t i{0}; } } -#line 7961 "reflect.h2" +#line 8145 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -11856,7 +12087,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -11911,7 +12142,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8030 "reflect.h2" +#line 8214 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12039,7 +12270,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8158 "reflect.h2" +#line 8342 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index ecda72902..a71c7b1e4 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4127,13 +4127,15 @@ autodiff_special_func: type = { autodiff_declared_variable: type = { public name : std::string = ""; public decl : std::string = ""; // TODO: Maybe use variant here. + public is_active: bool = false; public is_member: bool = false; operator=:(out this) = {} - operator=:(out this, name_: std::string, decl_: std::string, is_member_: bool) = { + operator=:(out this, name_: std::string, decl_: std::string, is_active_: bool, is_member_: bool) = { name = name_; decl = decl_; + is_active = is_active_; is_member = is_member_; } @@ -4209,6 +4211,12 @@ autodiff_context: type = { "exp(_a1_)", "_ad1_.exp(_a1_)", ), + autodiff_special_func("sqrt", 1, /* is_member = */ false, + "sqrt(_a1_)", + "0.5 * _ad1_ / sqrt(_a1_)", + "sqrt(_a1_)", + "_ad1_.sqrt(_a1_)", + ), autodiff_special_func("push_back", 1, /* is_member = */ true, "_o_.push_back(_a1_);", "_od_.push_back(_ad1_);") @@ -4243,8 +4251,12 @@ autodiff_context: type = { } - add_variable_declaration: (inout this, name: std::string, type: std::string, is_member: bool = false) = { - declaration_stack.back().declared_variables_stack.back().push_back(autodiff_declared_variable(name, type, is_member)); + add_variable_declaration: (inout this, name: std::string, type: std::string, is_active: bool, is_member: bool = false) = { + declaration_stack.back().declared_variables_stack.back().push_back(autodiff_declared_variable(name, type, is_active, is_member)); + } + + is_variable_active: (inout this, name: std::string) -> bool = { + return lookup_variable_declaration(name).is_active; } create_namespace_stack: (inout this, t: meta::type_or_namespace_declaration) = { @@ -4273,6 +4285,27 @@ autodiff_context: type = { return "temp_(temporary_count)$"; } + is_type_active: (inout this, type: std::string) -> bool = { + decls := lookup_type_declaration(type); + r := false; + + if !decls.empty() { + assert(decls.ssize() == 1); + ada: autodiff_activity_check = (this&); + ada.pre_traverse(decls[0]); + r = ada.active; + } + + // TODO: Add template activity lookup. + + if !r { + // Declaration lookup did not yield an activity: Apply some heuristics. + r = type.contains("double"); + } + + return r; + } + get_fwd_ad_type: (inout this, type: std::string) -> std::string = { type_d := type; @@ -4362,7 +4395,7 @@ autodiff_context: type = { lookup_variable_declaration: (inout this, name: std::string) -> autodiff_declared_variable = { if name == "_" { - return autodiff_declared_variable(name, "_", false); + return autodiff_declared_variable(name, "_", false, false); } for std::ranges::views::reverse(declaration_stack) do (cur_context) { @@ -4559,6 +4592,92 @@ autodiff_diff_code: type = { // return v.fwd; // } +autodiff_activity_check: type = { + this: simple_traverser = (); + + public ctx : *autodiff_context; + public active: bool = false; + + operator=: (out this, ctx_: *autodiff_context) = { + ctx = ctx_; + } + + traverse: (override inout this, o: meta::object_declaration) = { + + type := o.type(); + + if "_" == type { + if o.has_initializer() { + pre_traverse(o.get_initializer()); + } + else { + // Assume active + active = true; + } + } + else { + active |= ctx*.is_type_active(type); + } + } + + traverse: (override inout this, primary: meta::primary_expression) = + { + if primary.is_identifier() { + active |= ctx*.is_variable_active(primary.to_string()); + } + else if primary.is_expression_list() { + for primary.as_expression_list().get_expressions() do (cur) { + pre_traverse(cur); + } + } + else if primary.is_literal() { + // TODO: Improve check + if primary.to_string().contains(".") { + active = true; + } + } + else if primary.is_declaration() { + pre_traverse(primary.as_declaration()); + } + else { + primary.error("AD: Unknown primary expression kind: (primary.to_string())$"); + } + } + + traverse: (override inout this, postfix: meta::postfix_expression) = + { + terms := postfix.get_terms(); + + is_func := false; + + (copy i := 0) + for terms next i += 1 do (term) { + if term.get_op() == "." { + continue; + } + if term.get_op() == "(" && i + 1 == terms.ssize() { // Function operator has to be the last + is_func = true; + continue; + } + else { + postfix.error("AD: Unknown operator for postfix expression. op: (term.get_op())$ expr: (postfix)$"); + } + } + + // TODO: Really check for members + if terms.ssize() != 1 { + active |= ctx*.is_variable_active(postfix.get_primary_expression().to_string()); + } + + if is_func { + // Check arguments of function + for terms.back().get_expression_list().get_expressions() do (cur) { + pre_traverse(cur); + } + } + } +} + autodiff_handler_base: type = { public ctx: *autodiff_context; @@ -4648,6 +4767,7 @@ autodiff_expression_handler: type = { primal: std::string = ""; fwd : std::string = ""; rws : std::string = ""; + active: bool = false; } handle_expression_list: (inout this, list: meta::expression_list) -> std::vector = { @@ -4670,45 +4790,53 @@ autodiff_expression_handler: type = { fwd = "this(ctx*.fwd_suffix)$." + fwd; rws = "this(ctx*.rws_suffix)$." + rws; } - return (primal, fwd, rws); + + if decl.is_active { + return (primal, fwd, rws, true); + } + else { + return (primal, "", "", false); + } + } else if term.is_expression_list() { exprs := term..as_expression_list()..get_expressions(); if exprs.ssize() != 1 { term.error("Can not handle multiple expressions. (term.to_string())"); - return ("error", "", ""); + return ("error", "", "", false); } expr := exprs[0]; bin_expr := expr..as_assignment_expression(); if bin_expr.terms_size() != 0 { term.error("Can not handle assign expr inside of expression. (expr.to_string())$"); - return ("error", "", ""); + return ("error", "", "", false); } - ad : autodiff_expression_handler = (ctx); - ad..pre_traverse(bin_expr.get_terms().front().get_term()); - t := ctx*.gen_temporary(); - ad.gen_declaration(t, "double"); // TODO: get type of expression - append(ad); - - r : primal_fwd_rws_name = (t, t + ctx*.fwd_suffix, t + ctx*.rws_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) - _ = t; - return r; + return handle_expression_term(bin_expr.get_terms().front().get_term()); } else { // Nothing special. A regular expression. expr := term; - ad : autodiff_expression_handler = (ctx); - ad..pre_traverse(expr); - t := ctx*.gen_temporary(); - ad.gen_declaration(t, "double"); // TODO: get type of expression - append(ad); + ada: autodiff_activity_check = (ctx); + ada.pre_traverse(expr); - r : primal_fwd_rws_name = (t, t + ctx*.fwd_suffix, t + ctx*.rws_suffix); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) - _ = t; - return r; + if ada.active { + + ad : autodiff_expression_handler = (ctx); + ad..pre_traverse(expr); + t := ctx*.gen_temporary(); + ad.gen_declaration(t, "double"); // TODO: get type of expression + append(ad); + + r : primal_fwd_rws_name = (t, t + ctx*.fwd_suffix, t + ctx*.rws_suffix, true); // TODO: Check why on return (t, t + ctx*.fwd_suffix) the primal is initialized empty. Probably because of the move(t) + _ = t; + return r; + } + else { + return (expr.to_string(), "", "", false); + } } } @@ -4799,7 +4927,12 @@ autodiff_expression_handler: type = { diff += "(object_d)$, "; } for args do (arg) { - diff += "(arg.primal)$, (arg.fwd)$,"; + if arg.active { + diff += "(arg.primal)$, (arg.fwd)$, "; + } + else { + diff += "(arg.primal)$, "; + } } diff += ");\n"; @@ -4952,8 +5085,10 @@ autodiff_expression_handler: type = { } var := handle_expression_term(term.get_term()); - fwd += var.fwd; - rws += "(var.rws)$ (op)$= _rb_;\n"; + if var.active { + fwd += var.fwd; + rws += "(var.rws)$ (op)$= _rb_;\n"; + } primal += var.primal; first = false; @@ -4967,17 +5102,11 @@ autodiff_expression_handler: type = { traverse: (override inout this, binexpr: meta::multiplicative_expression) = { terms := binexpr.get_terms(); - var := handle_expression_term(terms[0].get_term()); - arg_a := var.primal; - arg_a_d := var.fwd; - arg_a_b := var.rws; + var_a := handle_expression_term(terms[0].get_term()); i : int = 1; while i < terms.ssize() next i += 1 { - var = handle_expression_term(terms[i].get_term()); - arg_b := var.primal; - arg_b_d := var.fwd; - arg_b_b := var.rws; + var_b := handle_expression_term(terms[i].get_term()); op := terms[i].get_op().to_string(); @@ -4987,29 +5116,54 @@ autodiff_expression_handler: type = { if "*" == op { if ctx*.is_taylor() { - fwd = "(arg_a_d)$..mul((arg_b_d)$, (arg_a)$, (arg_b)$)"; - rws = "(arg_b_b)$ += (arg_a_d)$..mul(_rb_, (arg_a)$, _r_);\n" - "(arg_a_b)$ += (arg_b_d)$..mul(_rb_, (arg_b)$, _r_);"; + // TODO: Add taylor overloads + fwd = "(var_a.fwd)$..mul((var_b.fwd)$, (var_a.primal)$, (var_b.primal)$)"; + if var_a.active { + //fwd += "(var_b.primal)$ * (var_a.fwd)$"; + rws += "(var_a.rws)$ += (var_b.fwd)$..mul(_rb_, (var_b.primal)$, _r_);\n"; + } + if var_b.active { + if !fwd.empty() { fwd += " + "; } + //fwd += "(var_a.primal)$ * (var_b.fwd)$"; + rws = "(var_b.rws)$ += (var_a.fwd)$..mul(_rb_, (var_a.primal)$, _r_);\n"; + } } else { - fwd = "(arg_a)$ * (arg_b_d)$ + (arg_b)$ * (arg_a_d)$"; - rws = "(arg_b_b)$ += (arg_a)$ * _rb_;\n" - "(arg_a_b)$ += (arg_b)$ * _rb_;"; + if var_a.active { + fwd += "(var_b.primal)$ * (var_a.fwd)$"; + rws += "(var_a.rws)$ += (var_b.primal)$ * _rb_;\n"; + } + if var_b.active { + if !fwd.empty() { fwd += " + "; } + fwd += "(var_a.primal)$ * (var_b.fwd)$"; + rws = "(var_b.rws)$ += (var_a.primal)$ * _rb_;\n"; + } } - primal = "(arg_a)$ * (arg_b)$"; + primal = "(var_a.primal)$ * (var_b.primal)$"; } else if "/" == op { if ctx*.is_taylor() { - fwd = "(arg_a_d)$.div((arg_b_d)$, (arg_a)$, (arg_b)$)"; - rws = "(arg_b_b)$ -= (arg_a_d)$.mul(_rb_, (arg_a)$, _r_).div((arg_b_d)$.mul((arg_b_d)$, (arg_b)$, (arg_b)$), (arg_a)$ * _r_, (arg_b)$ * (arg_b)$);\n" - "(arg_a_b)$ += _rb_.div((arg_b_d)$, _r_, (arg_b)$);"; + // TODO: Add taylor overloads + fwd = "(var_a.fwd)$.div((var_b.fwd)$, (var_a.primal)$, (var_b.primal)$)"; + if var_a.active { + rws += "(var_a.rws)$ += _rb_.div((var_b.fwd)$, _r_, (var_b.primal)$);\n"; + } + if var_b.active { + rws += "(var_b.rws)$ -= (var_a.fwd)$.mul(_rb_, (var_a.primal)$, _r_).div((var_b.fwd)$.mul((var_b.fwd)$, (var_b.primal)$, (var_b.primal)$), (var_a.primal)$ * _r_, (var_b.primal)$ * (var_b.primal)$);\n"; + } } else { - fwd = "(arg_a_d)$ / (arg_b)$ - (arg_a)$ * (arg_b_d)$ / ((arg_b)$ * (arg_b)$)"; - rws = "(arg_b_b)$ -= (arg_a)$ * _rb_ / ((arg_b)$ * (arg_b)$);\n" - "(arg_a_b)$ += _rb_ / (arg_b)$;"; + if var_a.active { + fwd += "(var_a.fwd)$ / (var_b.primal)$"; + rws = "(var_a.rws)$ += _rb_ / (var_b.primal)$;\n"; + } + if var_b.active { + if !fwd.empty() { fwd += " + "; } + fwd += "-(var_a.primal)$ * (var_b.fwd)$ / ((var_b.primal)$ * (var_b.primal)$)"; + rws += "(var_b.rws)$ -= (var_a.primal)$ * _rb_ / ((var_b.primal)$ * (var_b.primal)$);\n"; + } } - primal = "(arg_a)$ / (arg_b)$"; + primal = "(var_a.primal)$ / (var_b.primal)$"; } else { binexpr.error( "unkown multiplicative operator '(op)$'"); @@ -5023,14 +5177,11 @@ autodiff_expression_handler: type = { } else { // Temporary - t := ctx*.gen_temporary(); - t_d := t + ctx*.fwd_suffix; - t_b := t + ctx*.rws_suffix; - gen_declaration(t, t_d, t_b, primal, fwd, rws, "", "", ""); - - arg_a = t; - arg_a_d = t_d; - arg_a_b = t_b; + var_a.primal = ctx*.gen_temporary(); + var_a.fwd = var_a.primal + ctx*.fwd_suffix; + var_a.rws = var_a.primal + ctx*.rws_suffix; + var_a.active = var_a.active | var_b.active; + gen_declaration(var_a.primal, var_a.fwd, var_a.rws, primal, fwd, rws, "", "", ""); } } } @@ -5159,28 +5310,50 @@ autodiff_stmt_handler: type = { lhs : std::string = o.name(); type : = o.type(); - fwd_ad_type : = ctx*.get_fwd_ad_type(type); + active := false; + if "_" != type { + active = ctx*.is_type_active(type); + } + else { + assert(o.has_initializer()); - prim_init: std::string = ""; - fwd_init : std::string = ""; + ada: autodiff_activity_check = (ctx); + ada.pre_traverse(o.get_initializer()); + active = ada.active; + } - if o.has_initializer() { - ad: autodiff_expression_handler = (ctx); - ad.pre_traverse(o.get_initializer()); - append(ad); + if active { - prim_init = " = " + ad.primal_expr; - fwd_init = " = " + ad.fwd_expr; + fwd_ad_type : = ctx*.get_fwd_ad_type(type); - if type == "_" && ad.fwd_expr == "()" { - // Special handling for auto initialization from a literal. - fwd_init = " = " + ctx*.get_fwd_ad_type("double") + "()"; + prim_init: std::string = ""; + fwd_init : std::string = ""; + + if o.has_initializer() { + ad: autodiff_expression_handler = (ctx); + ad.pre_traverse(o.get_initializer()); + append(ad); + + prim_init = " = " + ad.primal_expr; + fwd_init = " = " + ad.fwd_expr; + + if type == "_" && ad.fwd_expr == "()" { + // Special handling for auto initialization from a literal. + fwd_init = " = " + ctx*.get_fwd_ad_type("double") + "()"; + } } + diff += "(lhs)$(ctx*.fwd_suffix)$ : (fwd_ad_type)$(fwd_init)$;\n"; + diff += "(lhs)$ : (type)$(prim_init)$;\n"; + } + else { + diff += "(lhs)$: (type)$"; + if o.has_initializer() { + diff += " = (o.get_initializer().to_string())$"; + } + diff += ";\n"; } - diff += "(lhs)$(ctx*.fwd_suffix)$ : (fwd_ad_type)$(fwd_init)$;\n"; - diff += "(lhs)$ : (type)$(prim_init)$;\n"; - ctx*.add_variable_declaration(lhs, type); + ctx*.add_variable_declaration(lhs, type, active); } @@ -5266,7 +5439,7 @@ autodiff_stmt_handler: type = { diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; diff += "((param_style)$ (param_decl.name())$(ctx*.fwd_suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; - ctx*.add_variable_declaration("(param_decl.name())$", "(param_decl.type())$"); // TODO: Handle loop/compound context variable declarations. + ctx*.add_variable_declaration("(param_decl.name())$", "(param_decl.type())$", true); // TODO: Handle loop/compound context variable declarations. pre_traverse(stmt.get_for_body()); diff += "}\n"; @@ -5417,6 +5590,8 @@ autodiff_declaration_handler: type = { traverse: (override inout this, f: meta::function_declaration) = { ctx*.enter_function(); + // TODO: Add activity for member functions + diff.add_forward(" (f.name())$(ctx*.fwd_suffix)$: ("); diff.add_reverse_primal(" (f.name())$(ctx*.rws_suffix)$: ("); @@ -5444,17 +5619,26 @@ autodiff_declaration_handler: type = { } else { type := param.get_declaration().type(); - diff.add_forward("(fwd_pass_style)$ (name)$ : (type)$, "); - diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); - diff.add_reverse_primal("(fwd_pass_style)$ (name)$ : (type)$, "); - if ctx*.is_taylor() { - diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); - } - diff.add_reverse_primal("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$, "); + ada: autodiff_activity_check = (ctx); + ada.pre_traverse(param); + if ada.active { + diff.add_forward("(fwd_pass_style)$ (name)$ : (type)$, "); + diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); + + diff.add_reverse_primal("(fwd_pass_style)$ (name)$ : (type)$, "); + if ctx*.is_taylor() { + diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$, "); + } + diff.add_reverse_primal("(rws_pass_style)$ (name)$(ctx*.rws_suffix)$ : (ctx*.get_rws_ad_type(type))$, "); + } + else { + diff.add_forward("(fwd_pass_style)$ (name)$ : (type)$, "); + diff.add_reverse_primal("(fwd_pass_style)$ (name)$ : (type)$, "); + } - ctx*.add_variable_declaration(name, type); + ctx*.add_variable_declaration(name, type, ada.active); } } @@ -5518,7 +5702,7 @@ autodiff_declaration_handler: type = { diff.add_reverse_primal("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); } - ctx*.add_variable_declaration("(name)$", "(type)$"); + ctx*.add_variable_declaration("(name)$", "(type)$", true); // TODO_a: Add acitivty check } } @@ -5585,7 +5769,7 @@ autodiff_declaration_handler: type = { } diff = ""; - ctx*.add_variable_declaration("(o.name())$", "(o.type())$", true); + ctx*.add_variable_declaration("(o.name())$", "(o.type())$", true, true); // TODO_a: Add acitivty check } From e0b4a6aa4557cecd1e0b7a017827baf8ad8aa637 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 29 Aug 2025 08:33:40 +0200 Subject: [PATCH 45/54] Update for tests and acitivity analysis. --- regression-tests/pure2-autodiff.cpp2 | 11 +- .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 + .../test-results/pure2-autodiff.cpp | 282 ++-- .../test-results/pure2-autodiff.cpp2.output | 83 +- source/reflect.h | 1152 +++++++++-------- source/reflect.h2 | 46 +- 6 files changed, 876 insertions(+), 700 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index f7d46181f..96014fd2d 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -196,6 +196,10 @@ ad_test_reverse: @autodiff<"reverse"> @print type = { add_1: (x: double, y: double) -> (r: double) = { r = x + y; } + + mul_1: (x: double, y: double) -> (r: double) = { + r = x * y; + } } } @@ -257,7 +261,12 @@ main: () = { y_b: double = 0.0; w_b: double = 1.0; - write_output_reverse("x + y", x, y, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_1_b(x, x_b, y, y_b, w_b)); + + _ = x_b; + _ = y_b; + _ = w_b; r_twice := ad_test_twice::mul_1_d_d2(x, x_d, x_d, 0.0); std::cout << "2nd order diff of x*x at (x)$ = (r_twice.r_d_d2)$" << std::endl; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index b19924990..c04f34aa3 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -28,4 +28,6 @@ diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.0000 diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index a1f7ddf4b..6b7bc4fff 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -18,7 +18,10 @@ class type_outer; #line 15 "pure2-autodiff.cpp2" class ad_test; -#line 193 "pure2-autodiff.cpp2" +#line 194 "pure2-autodiff.cpp2" +class ad_test_reverse; + +#line 204 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -351,12 +354,38 @@ public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cp #line 192 "pure2-autodiff.cpp2" }; + +class ad_test_reverse { +using add_1_ret = double; + + +#line 196 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; +using mul_1_ret = double; + + +#line 200 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; +using add_1_b_ret = double; + + public: [[nodiscard]] static auto add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret; + +using mul_1_b_ret = double; +public: [[nodiscard]] static auto mul_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_1_b_ret; + + public: ad_test_reverse() = default; + public: ad_test_reverse(ad_test_reverse const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(ad_test_reverse const&) -> void = delete; + + +#line 203 "pure2-autodiff.cpp2" +}; } class ad_test_twice { using mul_1_ret = double; -#line 196 "pure2-autodiff.cpp2" +#line 207 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -376,12 +405,15 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 199 "pure2-autodiff.cpp2" +#line 210 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 205 "pure2-autodiff.cpp2" +#line 216 "pure2-autodiff.cpp2" +auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, cpp2::impl::in r_b, auto const& ret) -> void; + +#line 222 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -402,14 +434,14 @@ return std::move(ret.value()); } } [[nodiscard]] auto type_outer::add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in b_d) const& -> add_d_ret{ - double r {}; - double r_d {};r_d = this_d.a_d + b_d; + double r {}; + double r_d {};r_d = this_d.a_d + b_d; r = a + b; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_d_ret{ - double ret {0.0}; - double ret_d {0.0};ret_d = x_d + y_d; + double ret {0.0}; + double ret_d {0.0};ret_d = x_d + y_d; ret = x + y; return { std::move(ret), std::move(ret_d) }; } @@ -684,102 +716,102 @@ return std::move(ret.value()); } return std::move(r.value()); } [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_1_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d; + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_2_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d + x_d; + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d + x_d; r = x + y + x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_1_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d - y_d; + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d; r = x - y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sub_2_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d - y_d - x_d; + double r {0.0}; + double r_d {0.0};r_d = x_d - y_d - x_d; r = x - y - x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_sub_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_sub_2_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d + y_d - x_d; + double r {0.0}; + double r_d {0.0};r_d = x_d + y_d - x_d; r = x + y - x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_1_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x * y_d + y * x_d; + double r {0.0}; + double r_d {0.0};r_d = y * x_d + x * y_d; r = x * y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_2_d_ret{ - double r {0.0}; - double r_d {0.0}; -auto temp_1_d {x * y_d + y * x_d}; + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {y * x_d + x * y_d}; auto temp_1 {x * y}; - r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); + r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; r = cpp2::move(temp_1) * x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_1_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_1_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + double r {0.0}; + double r_d {0.0};r_d = x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) + -x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> div_2_d_ret{ - double r {0.0}; - double r_d {0.0}; -auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) - x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),y) + -x * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y))}; auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; - r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) - temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); + r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),y) + -temp_1 * y_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y_d),(y * y)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),y); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_div_2_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_div_2_d_ret{ - double r {0.0}; - double r_d {0.0}; -auto temp_1_d {x * y_d + y * x_d}; + double r {0.0}; + double r_d {0.0}; +auto temp_1_d {y * x_d + x * y_d}; auto temp_1 {x * y}; - r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) - temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); + r_d = cpp2::move(temp_1_d) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1_d)),x) + -temp_1 * x_d / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x_d),(x * x)); r = cpp2::move(temp_1) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(cpp2::move(temp_1)),x); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> mul_add_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double temp_1_d {x_d + y_d}; double temp_1 {x + y}; - r_d = x * cpp2::move(temp_1_d) + temp_1 * x_d; + r_d = temp_1 * x_d + x * cpp2::move(temp_1_d); r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> add_mul_d_ret{ - double r {0.0}; - double r_d {0.0}; -double temp_1_d {x * y_d + y * x_d}; + double r {0.0}; + double r_d {0.0}; +double temp_1_d {y * x_d + x * y_d}; double temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d); @@ -788,8 +820,8 @@ double temp_1_d {x * y_d + y * x_d}; } [[nodiscard]] auto ad_test::prefix_add_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_add_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double temp_1_d {+x_d}; double temp_1 {+x}; @@ -799,8 +831,8 @@ double temp_1_d {+x_d}; } [[nodiscard]] auto ad_test::prefix_sub_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> prefix_sub_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double temp_1_d {-x_d}; double temp_1 {-x}; @@ -810,41 +842,41 @@ double temp_1_d {-x_d}; } [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_d_ret{ - double ret {0.0}; - double ret_d {0.0};ret_d = x_d + y_d; + double ret {0.0}; + double ret_d {0.0};ret_d = x_d + y_d; ret = x + y; return { std::move(ret), std::move(ret_d) }; } [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_call_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; auto temp_1 {func_d(x, x_d, y, y_d)}; double temp_2_d {temp_1.ret_d}; double temp_2 {cpp2::move(temp_1).ret}; - r_d = x * cpp2::move(temp_2_d) + temp_2 * x_d; + r_d = temp_2 * x_d + x * cpp2::move(temp_2_d); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::func_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> func_outer_call_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; auto temp_1 {func_outer_d(x, x_d, y, y_d)}; double temp_2_d {temp_1.ret_d}; double temp_2 {cpp2::move(temp_1).ret}; - r_d = x * cpp2::move(temp_2_d) + temp_2 * x_d; + r_d = temp_2 * x_d + x * cpp2::move(temp_2_d); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> sin_call_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double temp_1_d {x_d - y_d}; double temp_1 {x - y}; @@ -854,8 +886,8 @@ double temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::if_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_branch_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x_d; + double r {0.0}; + double r_d {0.0};r_d = x_d; r = x; if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; @@ -867,8 +899,8 @@ double temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::if_else_branch_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> if_else_branch_d_ret{ - double r {0.0}; - double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { + double r {0.0}; + double r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; r = y; } @@ -880,14 +912,14 @@ double temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::direct_return_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> direct_return_d_ret{ - double r {}; - double r_d {};r_d = x_d + y_d; + double r {}; + double r_d {};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::intermediate_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_var_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double t_d {x_d + y_d}; double t {x + y}; @@ -897,23 +929,19 @@ double t_d {x_d + y_d}; } [[nodiscard]] auto ad_test::intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_passive_var_d_ret{ - double r {0.0}; - double r_d {0.0}; -int i_d {}; - - int i {}; + double r {0.0}; + double r_d {0.0}; +int i {}; r_d = x_d + y_d; r = x + y; - i_d = { }; i = 2; - static_cast(cpp2::move(i_d)); static_cast(cpp2::move(i)); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_untyped_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; auto t_d {double()}; auto t {0.0}; @@ -925,8 +953,8 @@ auto t_d {double()}; } [[nodiscard]] auto ad_test::intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_default_init_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; double t_d {}; double t {}; @@ -938,8 +966,8 @@ double t_d {}; } [[nodiscard]] auto ad_test::intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> intermediate_no_init_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; cpp2::impl::deferred_init t_d; cpp2::impl::deferred_init t; @@ -951,11 +979,9 @@ cpp2::impl::deferred_init t_d; } [[nodiscard]] auto ad_test::while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_d_ret{ - double r {0.0}; - double r_d {0.0}; -int i_d {}; - - int i {0}; + double r {0.0}; + double r_d {0.0}; +int i {0}; r_d = x_d; r = x; for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { @@ -966,11 +992,9 @@ int i_d {}; } [[nodiscard]] auto ad_test::do_while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_d_ret{ - double r {0.0}; - double r_d {0.0}; -int i_d {}; - - int i {0}; + double r {0.0}; + double r_d {0.0}; +int i {0}; r_d = x_d; r = x; do { @@ -986,8 +1010,8 @@ int i_d {}; } [[nodiscard]] auto ad_test::for_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> for_loop_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; std::vector v_d {}; std::vector v {}; @@ -1014,8 +1038,8 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; } [[nodiscard]] auto ad_test::type_outer_use_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_use_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; type_outer_d t_d {}; type_outer t {}; @@ -1031,8 +1055,8 @@ type_outer_d t_d {}; } [[nodiscard]] auto ad_test::type_outer_call_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> type_outer_call_d_ret{ - double r {0.0}; - double r_d {0.0}; + double r {0.0}; + double r_d {0.0}; type_outer_d t_d {}; type_outer t {}; @@ -1045,40 +1069,66 @@ type_outer_d t_d {}; return { std::move(r), std::move(r_d) }; } -#line 193 "pure2-autodiff.cpp2" +#line 196 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ + cpp2::impl::deferred_init r; +#line 197 "pure2-autodiff.cpp2" + r.construct(x + y); + return std::move(r.value()); } + +#line 200 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ + cpp2::impl::deferred_init r; +#line 201 "pure2-autodiff.cpp2" + r.construct(x * y); + return std::move(r.value()); } + + [[nodiscard]] auto ad_test_reverse::add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret{ + double r {0.0};r = x + y; + x_b += r_b; + y_b += r_b; + return r; } + + [[nodiscard]] auto ad_test_reverse::mul_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_1_b_ret{ + double r {0.0};r = x * y; + x_b += y * r_b; + y_b += x * r_b; + return r; } + +#line 204 "pure2-autodiff.cpp2" } -#line 196 "pure2-autodiff.cpp2" +#line 207 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 197 "pure2-autodiff.cpp2" +#line 208 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } [[nodiscard]] auto ad_test_twice::mul_1_d(cpp2::impl::in x, cpp2::impl::in x_d) -> mul_1_d_ret{ - double r {0.0}; - double r_d {0.0};r_d = x * x_d + x * x_d; + double r {0.0}; + double r_d {0.0};r_d = x * x_d + x * x_d; r = x * x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test_twice::mul_1_d2(cpp2::impl::in x, cpp2::impl::in x_d2) -> mul_1_d2_ret{ - double r {0.0}; - double r_d2 {0.0};r_d2 = x * x_d2 + x * x_d2; + double r {0.0}; + double r_d2 {0.0};r_d2 = x * x_d2 + x * x_d2; r = x * x; return { std::move(r), std::move(r_d2) }; } [[nodiscard]] auto ad_test_twice::mul_1_d_d2(cpp2::impl::in x, cpp2::impl::in x_d2, cpp2::impl::in x_d, cpp2::impl::in x_d_d2) -> mul_1_d_d2_ret{ - double r {0.0}; - double r_d2 {0.0}; - double r_d {0.0}; - double r_d_d2 {0.0}; -double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; + double r {0.0}; + double r_d2 {0.0}; + double r_d {0.0}; + double r_d_d2 {0.0}; +double temp_1_d2 {x_d * x_d2 + x * x_d_d2}; double temp_1 {x * x_d}; - double temp_2_d2 {x * x_d_d2 + x_d * x_d2}; + double temp_2_d2 {x_d * x_d2 + x * x_d_d2}; double temp_2 {x * x_d}; r_d_d2 = cpp2::move(temp_1_d2) + cpp2::move(temp_2_d2); @@ -1088,12 +1138,19 @@ double temp_1_d2 {x * x_d_d2 + x_d * x_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 201 "pure2-autodiff.cpp2" +#line 212 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 205 "pure2-autodiff.cpp2" +#line 216 "pure2-autodiff.cpp2" +auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, cpp2::impl::in r_b, auto const& ret) -> void{ + std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", y = " + cpp2::to_string(y) + ", r_b = " + cpp2::to_string(r_b) + ") = (r = " + cpp2::to_string(ret) + ", x_b = " + cpp2::to_string(x_b) + ", y_b = " + cpp2::to_string(y_b) + ")" << std::endl; + x_b = 0.0; + y_b = 0.0; +} + +#line 222 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -1130,7 +1187,18 @@ auto main() -> int{ write_output("do while loop", x, x_d, y, y_d, ad_name::ad_test::do_while_loop_d(x, x_d, y, y_d)); write_output("for loop", x, x_d, y, y_d, ad_name::ad_test::for_loop_d(x, x_d, y, y_d)); write_output("tye_outer.a + y", x, x_d, y, y_d, ad_name::ad_test::type_outer_use_d(x, x_d, y, y_d)); - write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, cpp2::move(y), cpp2::move(y_d))); + write_output("type_outer.add(y)", x, x_d, y, y_d, ad_name::ad_test::type_outer_call_d(x, x_d, y, cpp2::move(y_d))); + + double x_b {0.0}; + double y_b {0.0}; + double w_b {1.0}; + + write_output_reverse("x + y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_1_b(x, x_b, cpp2::move(y), y_b, w_b)); + + static_cast(cpp2::move(x_b)); + static_cast(cpp2::move(y_b)); + static_cast(cpp2::move(w_b)); auto r_twice {ad_test_twice::mul_1_d_d2(x, x_d, cpp2::move(x_d), 0.0)}; std::cout << "2nd order diff of x*x at " + cpp2::to_string(cpp2::move(x)) + " = " + cpp2::to_string(cpp2::move(r_twice).r_d_d2) + "" << std::endl; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 7b43c59f6..ace9227cc 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -411,7 +411,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - r_d = x * y_d + y * x_d; + r_d = y * x_d + x * y_d; r = x * y; return; } @@ -426,9 +426,9 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x * y_d + y * x_d; + temp_1_d: _ = y * x_d + x * y_d; temp_1: _ = x * y; - r_d = temp_1 * x_d + x * temp_1_d; + r_d = x * temp_1_d + temp_1 * x_d; r = temp_1 * x; return; } @@ -443,7 +443,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - r_d = x_d / y - x * y_d / (y * y); + r_d = x_d / y + -x * y_d / (y * y); r = x / y; return; } @@ -458,9 +458,9 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x_d / y - x * y_d / (y * y); + temp_1_d: _ = x_d / y + -x * y_d / (y * y); temp_1: _ = x / y; - r_d = temp_1_d / y - temp_1 * y_d / (y * y); + r_d = temp_1_d / y + -temp_1 * y_d / (y * y); r = temp_1 / y; return; } @@ -475,9 +475,9 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: _ = x * y_d + y * x_d; + temp_1_d: _ = y * x_d + x * y_d; temp_1: _ = x * y; - r_d = temp_1_d / x - temp_1 * x_d / (x * x); + r_d = temp_1_d / x + -temp_1 * x_d / (x * x); r = temp_1 / x; return; } @@ -494,7 +494,7 @@ ad_test:/* @autodiff @print */ type = { temp_1_d: double = x_d + y_d; temp_1: double = x + y; - r_d = x * temp_1_d + temp_1 * x_d; + r_d = temp_1 * x_d + x * temp_1_d; r = x * temp_1; return; } @@ -509,7 +509,7 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - temp_1_d: double = x * y_d + y * x_d; + temp_1_d: double = y * x_d + x * y_d; temp_1: double = x * y; r_d = x_d + temp_1_d; r = x + temp_1; @@ -578,7 +578,7 @@ ad_test:/* @autodiff @print */ type = temp_1: _ = func_d(x, x_d, y, y_d); temp_2_d: double = temp_1.ret_d; temp_2: double = temp_1.ret; - r_d = x * temp_2_d + temp_2 * x_d; + r_d = temp_2 * x_d + x * temp_2_d; r = x * temp_2; return; } @@ -596,7 +596,7 @@ ad_test:/* @autodiff @print */ type = temp_1: _ = func_outer_d(x, x_d, y, y_d); temp_2_d: double = temp_1.ret_d; temp_2: double = temp_1.ret; - r_d = x * temp_2_d + temp_2 * x_d; + r_d = temp_2 * x_d + x * temp_2_d; r = x * temp_2; return; } @@ -706,13 +706,10 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = (); i: int = (); r_d = x_d + y_d; r = x + y; - i_d = (); i = 2; - _ = i_d; _ = i; return; } @@ -784,7 +781,6 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -807,7 +803,6 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -896,6 +891,56 @@ ad_test:/* @autodiff @print */ type = } +ad_test_reverse:/* @autodiff<"reverse"> @print */ type = +{ + add_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y; + return; + } + + mul_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y; + return; + } + + add_1_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x + y; + x_b += r_b; + y_b += r_b; + return; + } + + mul_1_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x * y; + x_b += y * r_b; + y_b += x * r_b; + return; + } +} + + ad_test_twice:/* @autodiff @autodiff<"suffix=_d2"> @print */ type = { mul_1:(in x: double, ) -> (out r: double, ) = @@ -942,9 +987,9 @@ ad_test_twice:/* @autodiff @autodiff<"suffix=_d2"> @print */ type = out r_d_d2: double = 0.0, ) = { - temp_1_d2: double = x * x_d_d2 + x_d * x_d2; + temp_1_d2: double = x_d * x_d2 + x * x_d_d2; temp_1: double = x * x_d; - temp_2_d2: double = x * x_d_d2 + x_d * x_d2; + temp_2_d2: double = x_d * x_d2 + x * x_d_d2; temp_2: double = x * x_d; r_d_d2 = temp_1_d2 + temp_2_d2; r_d = temp_1 + temp_2; diff --git a/source/reflect.h b/source/reflect.h index 537c59b01..361304086 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -129,91 +129,91 @@ class autodiff_diff_code; class autodiff_activity_check; -#line 4681 "reflect.h2" +#line 4693 "reflect.h2" class autodiff_handler_base; -#line 4699 "reflect.h2" +#line 4711 "reflect.h2" class autodiff_expression_handler; -#line 5286 "reflect.h2" +#line 5298 "reflect.h2" class autodiff_stmt_handler; -#line 5569 "reflect.h2" +#line 5593 "reflect.h2" class autodiff_declaration_handler; -#line 5914 "reflect.h2" +#line 5938 "reflect.h2" class expression_flags; -#line 5930 "reflect.h2" +#line 5954 "reflect.h2" class regex_token; -#line 5957 "reflect.h2" +#line 5981 "reflect.h2" class regex_token_check; -#line 5978 "reflect.h2" +#line 6002 "reflect.h2" class regex_token_code; -#line 5999 "reflect.h2" +#line 6023 "reflect.h2" class regex_token_empty; -#line 6017 "reflect.h2" +#line 6041 "reflect.h2" class regex_token_list; -#line 6069 "reflect.h2" +#line 6093 "reflect.h2" class parse_context_group_state; -#line 6130 "reflect.h2" +#line 6154 "reflect.h2" class parse_context_branch_reset_state; -#line 6173 "reflect.h2" +#line 6197 "reflect.h2" class parse_context; -#line 6574 "reflect.h2" +#line 6598 "reflect.h2" class generation_function_context; -#line 6592 "reflect.h2" +#line 6616 "reflect.h2" class generation_context; -#line 6791 "reflect.h2" +#line 6815 "reflect.h2" class alternative_token; -#line 6806 "reflect.h2" +#line 6830 "reflect.h2" class alternative_token_gen; -#line 6871 "reflect.h2" +#line 6895 "reflect.h2" class any_token; -#line 6888 "reflect.h2" +#line 6912 "reflect.h2" class atomic_group_token; -#line 6918 "reflect.h2" +#line 6942 "reflect.h2" class char_token; -#line 7033 "reflect.h2" +#line 7057 "reflect.h2" class class_token; -#line 7257 "reflect.h2" +#line 7281 "reflect.h2" class group_ref_token; -#line 7394 "reflect.h2" +#line 7418 "reflect.h2" class group_token; -#line 7741 "reflect.h2" +#line 7765 "reflect.h2" class lookahead_lookbehind_token; -#line 7836 "reflect.h2" +#line 7860 "reflect.h2" class range_token; -#line 7993 "reflect.h2" +#line 8017 "reflect.h2" class special_range_token; -#line 8079 "reflect.h2" +#line 8103 "reflect.h2" template class regex_generator; -#line 8342 "reflect.h2" +#line 8366 "reflect.h2" } } @@ -1942,18 +1942,21 @@ class autodiff_activity_check: public simple_traverser { public: autodiff_activity_check(cpp2::impl::in ctx_); #line 4605 "reflect.h2" + public: auto traverse(cpp2::impl::in t) -> void override; + +#line 4617 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4623 "reflect.h2" +#line 4635 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; -#line 4647 "reflect.h2" +#line 4659 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_activity_check(autodiff_activity_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_activity_check const&) -> void = delete; -#line 4679 "reflect.h2" +#line 4691 "reflect.h2" }; class autodiff_handler_base { @@ -1962,21 +1965,21 @@ class autodiff_handler_base { public: autodiff_diff_code diff; public: autodiff_handler_base(cpp2::impl::in ctx_); -#line 4686 "reflect.h2" +#line 4698 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& ; -#line 4692 "reflect.h2" +#line 4704 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4697 "reflect.h2" +#line 4709 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4703 "reflect.h2" +#line 4715 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1985,31 +1988,31 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(cpp2::impl::in ctx_); -#line 4713 "reflect.h2" +#line 4725 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; -#line 4722 "reflect.h2" +#line 4734 "reflect.h2" public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; -#line 4731 "reflect.h2" +#line 4743 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4741 "reflect.h2" +#line 4753 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4747 "reflect.h2" +#line 4759 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4757 "reflect.h2" +#line 4769 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4766 "reflect.h2" +#line 4778 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -2019,176 +2022,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_rws_name(); -#line 4771 "reflect.h2" +#line 4783 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4782 "reflect.h2" +#line 4794 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4843 "reflect.h2" +#line 4855 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 4992 "reflect.h2" +#line 5004 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5027 "reflect.h2" +#line 5039 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5031 "reflect.h2" +#line 5043 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5035 "reflect.h2" +#line 5047 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5039 "reflect.h2" +#line 5051 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5043 "reflect.h2" +#line 5055 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5047 "reflect.h2" +#line 5059 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5051 "reflect.h2" +#line 5063 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5055 "reflect.h2" +#line 5067 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5059 "reflect.h2" +#line 5071 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5063 "reflect.h2" +#line 5075 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5067 "reflect.h2" +#line 5079 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5071 "reflect.h2" +#line 5083 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5102 "reflect.h2" +#line 5114 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5189 "reflect.h2" +#line 5201 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5193 "reflect.h2" +#line 5205 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5209 "reflect.h2" +#line 5221 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5249 "reflect.h2" +#line 5261 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5284 "reflect.h2" +#line 5296 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5290 "reflect.h2" +#line 5302 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5299 "reflect.h2" +#line 5311 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5304 "reflect.h2" +#line 5316 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5309 "reflect.h2" +#line 5321 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5360 "reflect.h2" +#line 5372 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5365 "reflect.h2" +#line 5377 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5370 "reflect.h2" +#line 5382 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5375 "reflect.h2" +#line 5387 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5383 "reflect.h2" +#line 5395 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5400 "reflect.h2" +#line 5412 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5450 "reflect.h2" +#line 5462 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5461 "reflect.h2" +#line 5473 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5465 "reflect.h2" +#line 5477 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5478 "reflect.h2" +#line 5502 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5482 "reflect.h2" +#line 5506 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5486 "reflect.h2" +#line 5510 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5490 "reflect.h2" +#line 5514 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5494 "reflect.h2" +#line 5518 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5498 "reflect.h2" +#line 5522 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5502 "reflect.h2" +#line 5526 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5506 "reflect.h2" +#line 5530 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5510 "reflect.h2" +#line 5534 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5514 "reflect.h2" +#line 5538 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5518 "reflect.h2" +#line 5542 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5522 "reflect.h2" +#line 5546 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5526 "reflect.h2" +#line 5550 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5531 "reflect.h2" +#line 5555 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5563 "reflect.h2" +#line 5587 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5567 "reflect.h2" +#line 5591 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5573 "reflect.h2" +#line 5597 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2198,37 +2201,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5585 "reflect.h2" +#line 5609 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5590 "reflect.h2" +#line 5614 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5748 "reflect.h2" +#line 5772 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5776 "reflect.h2" +#line 5800 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5800 "reflect.h2" +#line 5824 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5805 "reflect.h2" +#line 5829 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5808 "reflect.h2" +#line 5832 "reflect.h2" }; -#line 5811 "reflect.h2" +#line 5835 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5910 "reflect.h2" +#line 5934 "reflect.h2" using error_func = std::function x)>; -#line 5914 "reflect.h2" +#line 5938 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2263,20 +2266,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5922 "reflect.h2" +#line 5946 "reflect.h2" }; -#line 5930 "reflect.h2" +#line 5954 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5938 "reflect.h2" +#line 5962 "reflect.h2" public: explicit regex_token(); -#line 5943 "reflect.h2" +#line 5967 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2288,103 +2291,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5949 "reflect.h2" +#line 5973 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5955 "reflect.h2" +#line 5979 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5961 "reflect.h2" +#line 5985 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5968 "reflect.h2" +#line 5992 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5972 "reflect.h2" +#line 5996 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5973 "reflect.h2" +#line 5997 "reflect.h2" }; -#line 5976 "reflect.h2" +#line 6000 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 5982 "reflect.h2" +#line 6006 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 5989 "reflect.h2" +#line 6013 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5993 "reflect.h2" +#line 6017 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 5994 "reflect.h2" +#line 6018 "reflect.h2" }; -#line 5997 "reflect.h2" +#line 6021 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6003 "reflect.h2" +#line 6027 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6007 "reflect.h2" +#line 6031 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6011 "reflect.h2" +#line 6035 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6012 "reflect.h2" +#line 6036 "reflect.h2" }; -#line 6015 "reflect.h2" +#line 6039 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6021 "reflect.h2" +#line 6045 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6028 "reflect.h2" +#line 6052 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6034 "reflect.h2" +#line 6058 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6040 "reflect.h2" +#line 6064 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6048 "reflect.h2" +#line 6072 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2392,10 +2395,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6060 "reflect.h2" +#line 6084 "reflect.h2" }; -#line 6063 "reflect.h2" +#line 6087 "reflect.h2" // // Parse and generation context. // @@ -2411,33 +2414,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6083 "reflect.h2" +#line 6107 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6090 "reflect.h2" +#line 6114 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6102 "reflect.h2" +#line 6126 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6107 "reflect.h2" +#line 6131 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6111 "reflect.h2" +#line 6135 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6125 "reflect.h2" +#line 6149 "reflect.h2" }; -#line 6128 "reflect.h2" +#line 6152 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2450,25 +2453,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6146 "reflect.h2" +#line 6170 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6152 "reflect.h2" +#line 6176 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6159 "reflect.h2" +#line 6183 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6166 "reflect.h2" +#line 6190 "reflect.h2" }; -#line 6169 "reflect.h2" +#line 6193 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2484,7 +2487,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6185 "reflect.h2" +#line 6209 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2492,64 +2495,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6196 "reflect.h2" +#line 6220 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6209 "reflect.h2" +#line 6233 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6217 "reflect.h2" +#line 6241 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6221 "reflect.h2" +#line 6245 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6225 "reflect.h2" +#line 6249 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6237 "reflect.h2" +#line 6261 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6244 "reflect.h2" +#line 6268 "reflect.h2" public: auto next_alternative() & -> void; -#line 6250 "reflect.h2" +#line 6274 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6256 "reflect.h2" +#line 6280 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6260 "reflect.h2" +#line 6284 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6271 "reflect.h2" +#line 6295 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6275 "reflect.h2" +#line 6299 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6281 "reflect.h2" +#line 6305 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6285 "reflect.h2" +#line 6309 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6292 "reflect.h2" +#line 6316 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6303 "reflect.h2" +#line 6327 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2557,51 +2560,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6347 "reflect.h2" +#line 6371 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6359 "reflect.h2" +#line 6383 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6372 "reflect.h2" +#line 6396 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6395 "reflect.h2" +#line 6419 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6412 "reflect.h2" +#line 6436 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6433 "reflect.h2" +#line 6457 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6443 "reflect.h2" +#line 6467 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6447 "reflect.h2" +#line 6471 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6503 "reflect.h2" +#line 6527 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6542 "reflect.h2" +#line 6566 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6557 "reflect.h2" +#line 6581 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2613,10 +2616,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6568 "reflect.h2" +#line 6592 "reflect.h2" }; -#line 6571 "reflect.h2" +#line 6595 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2626,16 +2629,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6585 "reflect.h2" +#line 6609 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6588 "reflect.h2" +#line 6612 "reflect.h2" }; -#line 6591 "reflect.h2" +#line 6615 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2655,68 +2658,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6613 "reflect.h2" +#line 6637 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6619 "reflect.h2" +#line 6643 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6628 "reflect.h2" +#line 6652 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6639 "reflect.h2" +#line 6663 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6646 "reflect.h2" +#line 6670 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6666 "reflect.h2" +#line 6690 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6676 "reflect.h2" +#line 6700 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6699 "reflect.h2" +#line 6723 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6707 "reflect.h2" +#line 6731 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6711 "reflect.h2" +#line 6735 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6717 "reflect.h2" +#line 6741 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6723 "reflect.h2" +#line 6747 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6733 "reflect.h2" +#line 6757 "reflect.h2" public: auto finish_context() & -> void; -#line 6741 "reflect.h2" +#line 6765 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6747 "reflect.h2" +#line 6771 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6751 "reflect.h2" +#line 6775 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6755 "reflect.h2" +#line 6779 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6779 "reflect.h2" +#line 6803 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2724,7 +2727,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6785 "reflect.h2" +#line 6809 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2744,27 +2747,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6804 "reflect.h2" +#line 6828 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6810 "reflect.h2" +#line 6834 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6817 "reflect.h2" +#line 6841 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6834 "reflect.h2" +#line 6858 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6841 "reflect.h2" +#line 6865 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6854 "reflect.h2" +#line 6878 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2772,19 +2775,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6866 "reflect.h2" +#line 6890 "reflect.h2" }; -#line 6869 "reflect.h2" +#line 6893 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6875 "reflect.h2" +#line 6899 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6879 "reflect.h2" +#line 6903 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2792,7 +2795,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6884 "reflect.h2" +#line 6908 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2800,17 +2803,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6892 "reflect.h2" +#line 6916 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6903 "reflect.h2" +#line 6927 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6911 "reflect.h2" +#line 6935 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2818,7 +2821,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6914 "reflect.h2" +#line 6938 "reflect.h2" }; // Regex syntax: a @@ -2826,34 +2829,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6922 "reflect.h2" +#line 6946 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6931 "reflect.h2" +#line 6955 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6937 "reflect.h2" +#line 6961 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6941 "reflect.h2" +#line 6965 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6964 "reflect.h2" +#line 6988 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 6985 "reflect.h2" +#line 7009 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7003 "reflect.h2" +#line 7027 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7018 "reflect.h2" +#line 7042 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7024 "reflect.h2" +#line 7048 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2861,33 +2864,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7028 "reflect.h2" +#line 7052 "reflect.h2" }; -#line 7031 "reflect.h2" +#line 7055 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7037 "reflect.h2" +#line 7061 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7049 "reflect.h2" +#line 7073 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7175 "reflect.h2" +#line 7199 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7184 "reflect.h2" +#line 7208 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7189 "reflect.h2" +#line 7213 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2895,20 +2898,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7196 "reflect.h2" +#line 7220 "reflect.h2" }; -#line 7199 "reflect.h2" +#line 7223 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7240 "reflect.h2" +#line 7264 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7251 "reflect.h2" +#line 7275 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2918,20 +2921,20 @@ class class_token class group_ref_token : public regex_token { -#line 7261 "reflect.h2" +#line 7285 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7273 "reflect.h2" +#line 7297 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7374 "reflect.h2" +#line 7398 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7378 "reflect.h2" +#line 7402 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2939,10 +2942,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7381 "reflect.h2" +#line 7405 "reflect.h2" }; -#line 7384 "reflect.h2" +#line 7408 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2956,29 +2959,29 @@ class group_ref_token class group_token : public regex_token { -#line 7398 "reflect.h2" +#line 7422 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7420 "reflect.h2" +#line 7444 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7434 "reflect.h2" +#line 7458 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7593 "reflect.h2" +#line 7617 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7601 "reflect.h2" +#line 7625 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7619 "reflect.h2" +#line 7643 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7650 "reflect.h2" +#line 7674 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2987,25 +2990,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7657 "reflect.h2" +#line 7681 "reflect.h2" }; -#line 7660 "reflect.h2" +#line 7684 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7701 "reflect.h2" +#line 7725 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7721 "reflect.h2" +#line 7745 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7737 "reflect.h2" +#line 7761 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3013,20 +3016,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7745 "reflect.h2" +#line 7769 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7754 "reflect.h2" +#line 7778 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7765 "reflect.h2" +#line 7789 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7772 "reflect.h2" +#line 7796 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3034,26 +3037,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7775 "reflect.h2" +#line 7799 "reflect.h2" }; -#line 7778 "reflect.h2" +#line 7802 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7806 "reflect.h2" +#line 7830 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7834 "reflect.h2" +#line 7858 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7840 "reflect.h2" +#line 7864 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3063,22 +3066,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7920 "reflect.h2" +#line 7944 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7932 "reflect.h2" +#line 7956 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7945 "reflect.h2" +#line 7969 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7964 "reflect.h2" +#line 7988 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7974 "reflect.h2" +#line 7998 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7985 "reflect.h2" +#line 8009 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3086,16 +3089,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 7988 "reflect.h2" +#line 8012 "reflect.h2" }; -#line 7991 "reflect.h2" +#line 8015 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 7997 "reflect.h2" +#line 8021 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3104,7 +3107,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8027 "reflect.h2" +#line 8051 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3113,14 +3116,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8049 "reflect.h2" +#line 8073 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8071 "reflect.h2" +#line 8095 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3141,24 +3144,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8094 "reflect.h2" +#line 8118 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8129 "reflect.h2" +#line 8153 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8143 "reflect.h2" +#line 8167 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8155 "reflect.h2" +#line 8179 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8210 "reflect.h2" +#line 8234 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3169,7 +3172,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8342 "reflect.h2" +#line 8366 "reflect.h2" } } @@ -8485,6 +8488,19 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } #line 4605 "reflect.h2" + auto autodiff_activity_check::traverse(cpp2::impl::in t) -> void{ + for ( + auto const& m : CPP2_UFCS(get_members)(t) ) + { + if (CPP2_UFCS(is_object)(m) || CPP2_UFCS(is_member_object)(m)) { + pre_traverse(m); + } + + // TODO: Maybe also add functions. + } + } + +#line 4617 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in o) -> void{ auto type {o.type()}; @@ -8503,7 +8519,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4623 "reflect.h2" +#line 4635 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8528,7 +8544,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }}}} } -#line 4647 "reflect.h2" +#line 4659 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8537,7 +8553,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4654 "reflect.h2" +#line 4666 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8553,8 +8569,8 @@ auto i{0}; } // TODO: Really check for members -#line 4668 "reflect.h2" - if (CPP2_UFCS(ssize)(terms) != 1) { +#line 4680 "reflect.h2" + if (!(is_func) || CPP2_UFCS(ssize)(terms) != 1) { active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))); } @@ -8566,39 +8582,39 @@ auto i{0}; } } -#line 4686 "reflect.h2" +#line 4698 "reflect.h2" autodiff_handler_base::autodiff_handler_base(cpp2::impl::in ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4689 "reflect.h2" +#line 4701 "reflect.h2" } -#line 4686 "reflect.h2" +#line 4698 "reflect.h2" auto autodiff_handler_base::operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4689 "reflect.h2" +#line 4701 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4692 "reflect.h2" +#line 4704 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff.fwd += o.diff.fwd; diff.rws_primal += o.diff.rws_primal; diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4709 "reflect.h2" +#line 4721 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(cpp2::impl::in ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4711 "reflect.h2" +#line 4723 "reflect.h2" } -#line 4713 "reflect.h2" +#line 4725 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8608,7 +8624,7 @@ auto i{0}; } } -#line 4722 "reflect.h2" +#line 4734 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ auto r {rhs_b}; r = string_util::replace_all(r, "_r_", lhs); @@ -8618,7 +8634,7 @@ auto i{0}; return r; } -#line 4731 "reflect.h2" +#line 4743 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8629,14 +8645,14 @@ auto i{0}; CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4741 "reflect.h2" +#line 4753 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4743 "reflect.h2" +#line 4755 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4747 "reflect.h2" +#line 4759 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8647,13 +8663,13 @@ auto i{0}; CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4757 "reflect.h2" +#line 4769 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4759 "reflect.h2" +#line 4771 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4761 "reflect.h2" +#line 4773 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } @@ -8665,7 +8681,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8675,7 +8691,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4782 "reflect.h2" +#line 4794 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8737,7 +8753,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} }} } -#line 4843 "reflect.h2" +#line 4855 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8745,7 +8761,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4849 "reflect.h2" +#line 4861 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8759,7 +8775,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4861 "reflect.h2" +#line 4873 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8782,7 +8798,7 @@ auto i{0}; { auto i{0}; -#line 4882 "reflect.h2" +#line 4894 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8807,7 +8823,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4905 "reflect.h2" +#line 4917 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8895,7 +8911,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 4992 "reflect.h2" +#line 5004 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8918,7 +8934,7 @@ auto i{0}; { auto i{1}; -#line 5013 "reflect.h2" +#line 5025 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8928,69 +8944,69 @@ auto i{1}; } } -#line 5021 "reflect.h2" +#line 5033 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 5027 "reflect.h2" +#line 5039 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5031 "reflect.h2" +#line 5043 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5035 "reflect.h2" +#line 5047 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5039 "reflect.h2" +#line 5051 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5043 "reflect.h2" +#line 5055 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5047 "reflect.h2" +#line 5059 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5051 "reflect.h2" +#line 5063 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5055 "reflect.h2" +#line 5067 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5059 "reflect.h2" +#line 5071 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5063 "reflect.h2" +#line 5075 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5067 "reflect.h2" +#line 5079 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5071 "reflect.h2" +#line 5083 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9022,7 +9038,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5102 "reflect.h2" +#line 5114 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9049,7 +9065,7 @@ auto i{1}; if (var_b.active) { if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } //fwd += "(var_a.primal)$ * (var_b.fwd)$"; - rws = "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.fwd) + "..mul(_rb_, " + cpp2::to_string(var_a.primal) + ", _r_);\n"; + rws += "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.fwd) + "..mul(_rb_, " + cpp2::to_string(var_a.primal) + ", _r_);\n"; } } else { @@ -9060,7 +9076,7 @@ auto i{1}; if (var_b.active) { if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } fwd += "" + cpp2::to_string(var_a.primal) + " * " + cpp2::to_string(var_b.fwd) + ""; - rws = "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.primal) + " * _rb_;\n"; + rws += "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.primal) + " * _rb_;\n"; } } primal = "" + cpp2::to_string(var_a.primal) + " * " + cpp2::to_string(var_b.primal) + ""; @@ -9093,7 +9109,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5173 "reflect.h2" +#line 5185 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9110,12 +9126,12 @@ auto i{1}; } } -#line 5189 "reflect.h2" +#line 5201 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5193 "reflect.h2" +#line 5205 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9132,7 +9148,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5209 "reflect.h2" +#line 5221 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9141,7 +9157,7 @@ auto i{1}; { auto i{0}; -#line 5216 "reflect.h2" +#line 5228 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9156,7 +9172,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5229 "reflect.h2" +#line 5241 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9177,7 +9193,7 @@ auto i{0}; } } -#line 5249 "reflect.h2" +#line 5261 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9214,26 +9230,26 @@ auto i{0}; }}}} } -#line 5294 "reflect.h2" +#line 5306 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5297 "reflect.h2" +#line 5309 "reflect.h2" } -#line 5299 "reflect.h2" +#line 5311 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5304 "reflect.h2" +#line 5316 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5309 "reflect.h2" +#line 5321 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9284,22 +9300,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5360 "reflect.h2" +#line 5372 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5365 "reflect.h2" +#line 5377 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5370 "reflect.h2" +#line 5382 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5375 "reflect.h2" +#line 5387 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -9307,7 +9323,7 @@ auto i{0}; diff += "}\n"; } -#line 5383 "reflect.h2" +#line 5395 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9324,7 +9340,7 @@ auto i{0}; } } -#line 5400 "reflect.h2" +#line 5412 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -9374,7 +9390,7 @@ auto i{0}; }} } -#line 5450 "reflect.h2" +#line 5462 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9386,92 +9402,104 @@ auto i{0}; } } -#line 5461 "reflect.h2" +#line 5473 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5465 "reflect.h2" +#line 5477 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ - autodiff_expression_handler h_lhs {ctx}; - CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); + autodiff_activity_check ada {ctx}; + CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); + if ("_" == CPP2_UFCS(to_string)(CPP2_UFCS(get_lhs_postfix_expression)(binexpr))) { + CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(CPP2_UFCS(get_terms)(binexpr), 1))); + } + + if (cpp2::move(ada).active) { + autodiff_expression_handler h_lhs {ctx}; + CPP2_UFCS(pre_traverse)(h_lhs, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); - // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression - auto assignment_terms {CPP2_UFCS(get_terms)(binexpr)}; + // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression + auto assignment_terms {CPP2_UFCS(get_terms)(binexpr)}; - autodiff_expression_handler h {ctx}; - CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, cpp2::move(h_lhs).rws_expr); - append(cpp2::move(h)); + autodiff_expression_handler h {ctx}; + CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, cpp2::move(h_lhs).rws_expr); + append(cpp2::move(h)); + } + else { + CPP2_UFCS(add_forward)(diff, CPP2_UFCS(to_string)(binexpr) + ";\n"); + CPP2_UFCS(add_reverse_primal)(diff, CPP2_UFCS(to_string)(binexpr) + ";\n"); + } } -#line 5478 "reflect.h2" +#line 5502 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5482 "reflect.h2" +#line 5506 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5486 "reflect.h2" +#line 5510 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5490 "reflect.h2" +#line 5514 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5494 "reflect.h2" +#line 5518 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5498 "reflect.h2" +#line 5522 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5502 "reflect.h2" +#line 5526 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5506 "reflect.h2" +#line 5530 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5510 "reflect.h2" +#line 5534 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5514 "reflect.h2" +#line 5538 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5518 "reflect.h2" +#line 5542 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5522 "reflect.h2" +#line 5546 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5526 "reflect.h2" +#line 5550 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5531 "reflect.h2" +#line 5555 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9480,7 +9508,7 @@ auto i{0}; { auto i{0}; -#line 5538 "reflect.h2" +#line 5562 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9495,7 +9523,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5551 "reflect.h2" +#line 5575 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9508,27 +9536,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5563 "reflect.h2" +#line 5587 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5580 "reflect.h2" +#line 5604 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5583 "reflect.h2" +#line 5607 "reflect.h2" } -#line 5585 "reflect.h2" +#line 5609 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5590 "reflect.h2" +#line 5614 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9658,10 +9686,10 @@ auto i{0}; return ; } -#line 5720 "reflect.h2" +#line 5744 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5723 "reflect.h2" +#line 5747 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9686,7 +9714,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5748 "reflect.h2" +#line 5772 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9714,7 +9742,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5776 "reflect.h2" +#line 5800 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9738,17 +9766,17 @@ auto i{0}; } } -#line 5800 "reflect.h2" +#line 5824 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5805 "reflect.h2" +#line 5829 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5811 "reflect.h2" +#line 5835 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9924,7 +9952,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5896 "reflect.h2" +#line 5920 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9940,11 +9968,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5912 "reflect.h2" +#line 5936 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5916 "reflect.h2" +#line 5940 "reflect.h2" // mod: i // mod: m // mod: s @@ -9952,116 +9980,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5925 "reflect.h2" +#line 5949 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5934 "reflect.h2" +#line 5958 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5936 "reflect.h2" +#line 5960 "reflect.h2" } -#line 5938 "reflect.h2" +#line 5962 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5940 "reflect.h2" +#line 5964 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5946 "reflect.h2" +#line 5970 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5947 "reflect.h2" +#line 5971 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5948 "reflect.h2" +#line 5972 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5963 "reflect.h2" +#line 5987 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5966 "reflect.h2" +#line 5990 "reflect.h2" } -#line 5968 "reflect.h2" +#line 5992 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5972 "reflect.h2" +#line 5996 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 5984 "reflect.h2" +#line 6008 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 5987 "reflect.h2" +#line 6011 "reflect.h2" } -#line 5989 "reflect.h2" +#line 6013 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 5993 "reflect.h2" +#line 6017 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6003 "reflect.h2" +#line 6027 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6005 "reflect.h2" +#line 6029 "reflect.h2" } -#line 6007 "reflect.h2" +#line 6031 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6011 "reflect.h2" +#line 6035 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6023 "reflect.h2" +#line 6047 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6026 "reflect.h2" +#line 6050 "reflect.h2" } -#line 6028 "reflect.h2" +#line 6052 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6034 "reflect.h2" +#line 6058 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6040 "reflect.h2" +#line 6064 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10070,7 +10098,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6048 "reflect.h2" +#line 6072 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10086,7 +10114,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6076 "reflect.h2" +#line 6100 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10094,14 +10122,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6084 "reflect.h2" +#line 6108 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6091 "reflect.h2" +#line 6115 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10113,15 +10141,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6103 "reflect.h2" +#line 6127 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6108 "reflect.h2" +#line 6132 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6112 "reflect.h2" +#line 6136 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10142,7 +10170,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6138 "reflect.h2" +#line 6162 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10151,20 +10179,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6147 "reflect.h2" +#line 6171 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6153 "reflect.h2" +#line 6177 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6160 "reflect.h2" +#line 6184 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10179,16 +10207,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6190 "reflect.h2" +#line 6214 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6194 "reflect.h2" +#line 6218 "reflect.h2" } -#line 6200 "reflect.h2" +#line 6224 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10198,7 +10226,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6210 "reflect.h2" +#line 6234 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10206,17 +10234,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6217 "reflect.h2" +#line 6241 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6221 "reflect.h2" +#line 6245 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6228 "reflect.h2" +#line 6252 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10226,7 +10254,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6237 "reflect.h2" +#line 6261 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10234,24 +10262,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6244 "reflect.h2" +#line 6268 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6252 "reflect.h2" +#line 6276 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6256 "reflect.h2" +#line 6280 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6260 "reflect.h2" +#line 6284 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10263,22 +10291,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6271 "reflect.h2" +#line 6295 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6277 "reflect.h2" +#line 6301 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6281 "reflect.h2" +#line 6305 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6285 "reflect.h2" +#line 6309 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10286,7 +10314,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6292 "reflect.h2" +#line 6316 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10298,10 +10326,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6305 "reflect.h2" +#line 6329 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6308 "reflect.h2" +#line 6332 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10341,7 +10369,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6348 "reflect.h2" +#line 6372 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10353,14 +10381,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6359 "reflect.h2" +#line 6383 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6360 "reflect.h2" +#line 6384 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6361 "reflect.h2" +#line 6385 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6363 "reflect.h2" +#line 6387 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10370,10 +10398,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6372 "reflect.h2" +#line 6396 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6374 "reflect.h2" +#line 6398 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10395,14 +10423,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6395 "reflect.h2" +#line 6419 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6396 "reflect.h2" +#line 6420 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6397 "reflect.h2" +#line 6421 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6399 "reflect.h2" +#line 6423 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10416,7 +10444,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6412 "reflect.h2" +#line 6436 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10438,7 +10466,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6433 "reflect.h2" +#line 6457 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10449,12 +10477,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6443 "reflect.h2" +#line 6467 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6444 "reflect.h2" +#line 6468 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6449 "reflect.h2" +#line 6473 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10509,7 +10537,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6503 "reflect.h2" +#line 6527 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10549,7 +10577,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6542 "reflect.h2" +#line 6566 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10565,21 +10593,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6559 "reflect.h2" +#line 6583 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6560 "reflect.h2" +#line 6584 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6561 "reflect.h2" +#line 6585 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6563 "reflect.h2" +#line 6587 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6578 "reflect.h2" +#line 6602 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10587,7 +10615,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6585 "reflect.h2" +#line 6609 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10597,22 +10625,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6603 "reflect.h2" +#line 6627 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6608 "reflect.h2" +#line 6632 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6614 "reflect.h2" +#line 6638 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6620 "reflect.h2" +#line 6644 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10621,7 +10649,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6628 "reflect.h2" +#line 6652 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10633,7 +10661,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6639 "reflect.h2" +#line 6663 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10641,7 +10669,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6646 "reflect.h2" +#line 6670 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10662,7 +10690,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6667 "reflect.h2" +#line 6691 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10672,7 +10700,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6677 "reflect.h2" +#line 6701 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10695,33 +10723,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6701 "reflect.h2" +#line 6725 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6707 "reflect.h2" +#line 6731 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6711 "reflect.h2" +#line 6735 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6717 "reflect.h2" +#line 6741 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6725 "reflect.h2" +#line 6749 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10730,7 +10758,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6733 "reflect.h2" +#line 6757 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10739,22 +10767,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6743 "reflect.h2" +#line 6767 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6747 "reflect.h2" +#line 6771 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6751 "reflect.h2" +#line 6775 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6755 "reflect.h2" +#line 6779 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10778,18 +10806,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6780 "reflect.h2" +#line 6804 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6795 "reflect.h2" +#line 6819 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6797 "reflect.h2" +#line 6821 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10800,15 +10828,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6812 "reflect.h2" +#line 6836 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6815 "reflect.h2" +#line 6839 "reflect.h2" } -#line 6817 "reflect.h2" +#line 6841 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10826,7 +10854,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6834 "reflect.h2" +#line 6858 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10834,7 +10862,7 @@ generation_function_context::generation_function_context(){} } } -#line 6841 "reflect.h2" +#line 6865 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10848,7 +10876,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6854 "reflect.h2" +#line 6878 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10864,14 +10892,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6875 "reflect.h2" +#line 6899 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6877 "reflect.h2" +#line 6901 "reflect.h2" } -#line 6879 "reflect.h2" +#line 6903 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10880,11 +10908,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6894 "reflect.h2" +#line 6918 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6896 "reflect.h2" +#line 6920 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10892,7 +10920,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6903 "reflect.h2" +#line 6927 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10901,37 +10929,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6911 "reflect.h2" +#line 6935 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6925 "reflect.h2" +#line 6949 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6929 "reflect.h2" +#line 6953 "reflect.h2" } -#line 6931 "reflect.h2" +#line 6955 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6935 "reflect.h2" +#line 6959 "reflect.h2" } -#line 6937 "reflect.h2" +#line 6961 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6941 "reflect.h2" +#line 6965 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10940,14 +10968,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6947 "reflect.h2" +#line 6971 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6952 "reflect.h2" +#line 6976 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10960,7 +10988,7 @@ size_t i{0}; } } -#line 6964 "reflect.h2" +#line 6988 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -10982,7 +11010,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 6985 "reflect.h2" +#line 7009 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11001,7 +11029,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7003 "reflect.h2" +#line 7027 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11017,14 +11045,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7018 "reflect.h2" +#line 7042 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7024 "reflect.h2" +#line 7048 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11032,19 +11060,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7041 "reflect.h2" +#line 7065 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7042 "reflect.h2" +#line 7066 "reflect.h2" { -#line 7047 "reflect.h2" +#line 7071 "reflect.h2" } -#line 7050 "reflect.h2" +#line 7074 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11170,7 +11198,7 @@ size_t i{0}; ); } -#line 7175 "reflect.h2" +#line 7199 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11180,13 +11208,13 @@ size_t i{0}; ); } -#line 7184 "reflect.h2" +#line 7208 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7189 "reflect.h2" +#line 7213 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11197,12 +11225,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7201 "reflect.h2" +#line 7225 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7206 "reflect.h2" +#line 7230 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11236,7 +11264,7 @@ size_t i{0}; } -#line 7242 "reflect.h2" +#line 7266 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11245,19 +11273,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7265 "reflect.h2" +#line 7289 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7266 "reflect.h2" +#line 7290 "reflect.h2" { -#line 7271 "reflect.h2" +#line 7295 "reflect.h2" } -#line 7273 "reflect.h2" +#line 7297 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11359,19 +11387,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7374 "reflect.h2" +#line 7398 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7378 "reflect.h2" +#line 7402 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7402 "reflect.h2" +#line 7426 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11390,7 +11418,7 @@ size_t i{0}; return r; } -#line 7420 "reflect.h2" +#line 7444 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11405,7 +11433,7 @@ size_t i{0}; return r; } -#line 7434 "reflect.h2" +#line 7458 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11565,7 +11593,7 @@ size_t i{0}; } } -#line 7593 "reflect.h2" +#line 7617 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11574,7 +11602,7 @@ size_t i{0}; return r; } -#line 7601 "reflect.h2" +#line 7625 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11593,7 +11621,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7619 "reflect.h2" +#line 7643 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11625,7 +11653,7 @@ size_t i{0}; } } -#line 7650 "reflect.h2" +#line 7674 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11636,7 +11664,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7662 "reflect.h2" +#line 7686 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11675,7 +11703,7 @@ size_t i{0}; return r; } -#line 7703 "reflect.h2" +#line 7727 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11693,7 +11721,7 @@ size_t i{0}; }} } -#line 7723 "reflect.h2" +#line 7747 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11707,16 +11735,16 @@ size_t i{0}; } } -#line 7749 "reflect.h2" +#line 7773 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7752 "reflect.h2" +#line 7776 "reflect.h2" } -#line 7754 "reflect.h2" +#line 7778 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11728,7 +11756,7 @@ size_t i{0}; } } -#line 7765 "reflect.h2" +#line 7789 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11736,14 +11764,14 @@ size_t i{0}; return r; } -#line 7772 "reflect.h2" +#line 7796 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7780 "reflect.h2" +#line 7804 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11769,7 +11797,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7808 "reflect.h2" +#line 7832 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11795,11 +11823,11 @@ size_t i{0}; return r; } -#line 7845 "reflect.h2" +#line 7869 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7847 "reflect.h2" +#line 7871 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11873,7 +11901,7 @@ size_t i{0}; return nullptr; } -#line 7920 "reflect.h2" +#line 7944 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11886,7 +11914,7 @@ size_t i{0}; }} } -#line 7932 "reflect.h2" +#line 7956 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11900,7 +11928,7 @@ size_t i{0}; }} } -#line 7945 "reflect.h2" +#line 7969 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11920,7 +11948,7 @@ size_t i{0}; return r; } -#line 7964 "reflect.h2" +#line 7988 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11931,7 +11959,7 @@ size_t i{0}; return r; } -#line 7974 "reflect.h2" +#line 7998 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11943,14 +11971,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7985 "reflect.h2" +#line 8009 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 7997 "reflect.h2" +#line 8021 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11974,7 +12002,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8021 "reflect.h2" +#line 8045 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -11984,7 +12012,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8033 "reflect.h2" +#line 8057 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12000,7 +12028,7 @@ size_t i{0}; } } -#line 8053 "reflect.h2" +#line 8077 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12018,15 +12046,15 @@ size_t i{0}; }} } -#line 8089 "reflect.h2" +#line 8113 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8092 "reflect.h2" +#line 8116 "reflect.h2" } -#line 8094 "reflect.h2" +#line 8118 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12062,7 +12090,7 @@ size_t i{0}; return source; } -#line 8129 "reflect.h2" +#line 8153 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12078,7 +12106,7 @@ size_t i{0}; } } -#line 8145 "reflect.h2" +#line 8169 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12087,7 +12115,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12142,7 +12170,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8214 "reflect.h2" +#line 8238 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12270,7 +12298,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8342 "reflect.h2" +#line 8366 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index a71c7b1e4..90ff18747 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4602,6 +4602,18 @@ autodiff_activity_check: type = { ctx = ctx_; } + traverse: (override inout this, t: meta::type_declaration) = { + for t.get_members() + do (m) + { + if m.is_object() || m.is_member_object() { + pre_traverse(m); + } + + // TODO: Maybe also add functions. + } + } + traverse: (override inout this, o: meta::object_declaration) = { type := o.type(); @@ -4665,7 +4677,7 @@ autodiff_activity_check: type = { } // TODO: Really check for members - if terms.ssize() != 1 { + if !is_func || terms.ssize() != 1 { active |= ctx*.is_variable_active(postfix.get_primary_expression().to_string()); } @@ -5125,7 +5137,7 @@ autodiff_expression_handler: type = { if var_b.active { if !fwd.empty() { fwd += " + "; } //fwd += "(var_a.primal)$ * (var_b.fwd)$"; - rws = "(var_b.rws)$ += (var_a.fwd)$..mul(_rb_, (var_a.primal)$, _r_);\n"; + rws += "(var_b.rws)$ += (var_a.fwd)$..mul(_rb_, (var_a.primal)$, _r_);\n"; } } else { @@ -5136,7 +5148,7 @@ autodiff_expression_handler: type = { if var_b.active { if !fwd.empty() { fwd += " + "; } fwd += "(var_a.primal)$ * (var_b.fwd)$"; - rws = "(var_b.rws)$ += (var_a.primal)$ * _rb_;\n"; + rws += "(var_b.rws)$ += (var_a.primal)$ * _rb_;\n"; } } primal = "(var_a.primal)$ * (var_b.primal)$"; @@ -5463,16 +5475,28 @@ autodiff_stmt_handler: type = { } traverse: (override inout this, binexpr: meta::assignment_expression) = { - h_lhs: autodiff_expression_handler = (ctx); - h_lhs.pre_traverse(binexpr.get_lhs_postfix_expression()); + ada: autodiff_activity_check = (ctx); + ada.pre_traverse(binexpr.get_lhs_postfix_expression()); + if "_" == binexpr.get_lhs_postfix_expression().to_string() { + ada.pre_traverse(binexpr.get_terms()[1].get_term()); + } + + if ada.active { + h_lhs: autodiff_expression_handler = (ctx); + h_lhs.pre_traverse(binexpr.get_lhs_postfix_expression()); - // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression - assignment_terms := binexpr.get_terms(); + // Cpp2 doesn't allow chained assignment, so rhs must be a single logical_or_expression + assignment_terms := binexpr.get_terms(); - h: autodiff_expression_handler = (ctx); - h.pre_traverse(assignment_terms[1].get_term()); - h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); - append(h); + h: autodiff_expression_handler = (ctx); + h.pre_traverse(assignment_terms[1].get_term()); + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); + append(h); + } + else { + diff.add_forward(binexpr.to_string() + ";\n"); + diff.add_reverse_primal(binexpr.to_string() + ";\n"); + } } traverse: (override inout this, binexpr: meta::logical_or_expression) = { From 7b3b9c82af95d4a7141815c202d37425bbafb05e Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 29 Aug 2025 09:16:23 +0200 Subject: [PATCH 46/54] Added tests for combined binary expressions. --- regression-tests/pure2-autodiff.cpp2 | 53 +- .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 10 + .../test-results/pure2-autodiff.cpp | 305 ++++- .../test-results/pure2-autodiff.cpp2.output | 270 +++++ source/reflect.h | 1055 +++++++++-------- source/reflect.h2 | 5 +- 6 files changed, 1153 insertions(+), 545 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 96014fd2d..651c519f2 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -197,9 +197,49 @@ ad_test_reverse: @autodiff<"reverse"> @print type = { r = x + y; } + add_2: (x: double, y: double) -> (r: double) = { + r = x + y + x; + } + + sub_1: (x: double, y: double) -> (r: double) = { + r = x - y; + } + + sub_2: (x: double, y: double) -> (r: double) = { + r = x - y - x; + } + + add_sub_2: (x: double, y: double) -> (r: double) = { + r = x + y - x; + } + mul_1: (x: double, y: double) -> (r: double) = { r = x * y; } + + mul_2: (x: double, y: double) -> (r: double) = { + r = x * y * x; + } + + div_1: (x: double, y: double) -> (r: double) = { + r = x / y; + } + + div_2: (x: double, y: double) -> (r: double) = { + r = x / y / y; + } + + mul_div_2: (x: double, y: double) -> (r: double) = { + r = x * y / x; + } + + mul_add: (x: double, y: double) -> (r: double) = { + r = x * (x + y); + } + + add_mul: (x: double, y: double) -> (r: double) = { + r = x + x * y; + } } } @@ -213,7 +253,8 @@ write_output: (func: std::string, x: double, x_d: double, y: double, y_d: double std::cout << "diff((func)$) at (x = (x)$, x_d = (x_d)$, y = (y)$, y_d = (y_d)$) = (r = (ret.r)$, r_d = (ret.r_d)$)" << std::endl; } -write_output_reverse: (func: std::string, x: double, inout x_b: double, y: double, inout y_b: double, in r_b: double, ret) = { +write_output_reverse: (func: std::string, x: double, inout x_b: double, y: double, inout y_b: double, inout r_b: double, ret) = { + r_b = 1.0; std::cout << "diff((func)$) at (x = (x)$, y = (y)$, r_b = (r_b)$) = (r = (ret)$, x_b = (x_b)$, y_b = (y_b)$)" << std::endl; x_b = 0.0; y_b = 0.0; @@ -262,7 +303,17 @@ main: () = { w_b: double = 1.0; write_output_reverse("x + y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + y + x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x - y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sub_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x - y - x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sub_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + y - x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_sub_2_b(x, x_b, y, y_b, w_b)); write_output_reverse("x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y * x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x / y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::div_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x / y / y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::div_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y / x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_div_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, y, y_b, w_b)); _ = x_b; _ = y_b; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index c04f34aa3..3d604f730 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -29,5 +29,15 @@ diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x + y + x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 7.000000, x_b = 2.000000, y_b = 1.000000) +diff(x - y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -1.000000, x_b = 1.000000, y_b = -1.000000) +diff(x - y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -3.000000, x_b = 0.000000, y_b = -1.000000) +diff(x + y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) +diff(x * y * x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 12.000000, x_b = 12.000000, y_b = 4.000000) +diff(x / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.666667, x_b = 0.333333, y_b = -0.222222) +diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, x_b = 0.111111, y_b = -0.148148) +diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 6b7bc4fff..bd9cec6c5 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -21,7 +21,7 @@ class ad_test; #line 194 "pure2-autodiff.cpp2" class ad_test_reverse; -#line 204 "pure2-autodiff.cpp2" +#line 244 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -361,31 +361,111 @@ using add_1_ret = double; #line 196 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; -using mul_1_ret = double; +using add_2_ret = double; #line 200 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; +using sub_1_ret = double; + + +#line 204 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; +using sub_2_ret = double; + + +#line 208 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; +using add_sub_2_ret = double; + + +#line 212 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; +using mul_1_ret = double; + + +#line 216 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; +using mul_2_ret = double; + + +#line 220 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; +using div_1_ret = double; + + +#line 224 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; +using div_2_ret = double; + + +#line 228 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; +using mul_div_2_ret = double; + + +#line 232 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; +using mul_add_ret = double; + + +#line 236 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; +using add_mul_ret = double; + + +#line 240 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using add_1_b_ret = double; public: [[nodiscard]] static auto add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret; +using add_2_b_ret = double; +public: [[nodiscard]] static auto add_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_2_b_ret; + +using sub_1_b_ret = double; +public: [[nodiscard]] static auto sub_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sub_1_b_ret; + +using sub_2_b_ret = double; +public: [[nodiscard]] static auto sub_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sub_2_b_ret; + +using add_sub_2_b_ret = double; +public: [[nodiscard]] static auto add_sub_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_sub_2_b_ret; + using mul_1_b_ret = double; public: [[nodiscard]] static auto mul_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_1_b_ret; +using mul_2_b_ret = double; +public: [[nodiscard]] static auto mul_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_2_b_ret; + +using div_1_b_ret = double; +public: [[nodiscard]] static auto div_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> div_1_b_ret; + +using div_2_b_ret = double; +public: [[nodiscard]] static auto div_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> div_2_b_ret; + +using mul_div_2_b_ret = double; +public: [[nodiscard]] static auto mul_div_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_div_2_b_ret; + +using mul_add_b_ret = double; +public: [[nodiscard]] static auto mul_add_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_add_b_ret; + +using add_mul_b_ret = double; +public: [[nodiscard]] static auto add_mul_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_mul_b_ret; + public: ad_test_reverse() = default; public: ad_test_reverse(ad_test_reverse const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test_reverse const&) -> void = delete; -#line 203 "pure2-autodiff.cpp2" +#line 243 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 207 "pure2-autodiff.cpp2" +#line 247 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -405,15 +485,15 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 210 "pure2-autodiff.cpp2" +#line 250 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 216 "pure2-autodiff.cpp2" -auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, cpp2::impl::in r_b, auto const& ret) -> void; +#line 256 "pure2-autodiff.cpp2" +auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void; -#line 222 "pure2-autodiff.cpp2" +#line 263 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -1077,31 +1157,211 @@ type_outer_d t_d {}; return std::move(r.value()); } #line 200 "pure2-autodiff.cpp2" - [[nodiscard]] auto ad_test_reverse::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ + [[nodiscard]] auto ad_test_reverse::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; #line 201 "pure2-autodiff.cpp2" + r.construct(x + y + x); + return std::move(r.value()); } + +#line 204 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ + cpp2::impl::deferred_init r; +#line 205 "pure2-autodiff.cpp2" + r.construct(x - y); + return std::move(r.value()); } + +#line 208 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ + cpp2::impl::deferred_init r; +#line 209 "pure2-autodiff.cpp2" + r.construct(x - y - x); + return std::move(r.value()); } + +#line 212 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ + cpp2::impl::deferred_init r; +#line 213 "pure2-autodiff.cpp2" + r.construct(x + y - x); + return std::move(r.value()); } + +#line 216 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ + cpp2::impl::deferred_init r; +#line 217 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } +#line 220 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ + cpp2::impl::deferred_init r; +#line 221 "pure2-autodiff.cpp2" + r.construct(x * y * x); + return std::move(r.value()); } + +#line 224 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ + cpp2::impl::deferred_init r; +#line 225 "pure2-autodiff.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); + return std::move(r.value()); } + +#line 228 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ + cpp2::impl::deferred_init r; +#line 229 "pure2-autodiff.cpp2" + r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); + return std::move(r.value()); } + +#line 232 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ + cpp2::impl::deferred_init r; +#line 233 "pure2-autodiff.cpp2" + r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); + return std::move(r.value()); } + +#line 236 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ + cpp2::impl::deferred_init r; +#line 237 "pure2-autodiff.cpp2" + r.construct(x * (x + y)); + return std::move(r.value()); } + +#line 240 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ + cpp2::impl::deferred_init r; +#line 241 "pure2-autodiff.cpp2" + r.construct(x + x * y); + return std::move(r.value()); } + [[nodiscard]] auto ad_test_reverse::add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret{ double r {0.0};r = x + y; x_b += r_b; y_b += r_b; + r_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::add_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_2_b_ret{ + double r {0.0};r = x + y + x; + x_b += r_b; + y_b += r_b; + x_b += r_b; + r_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::sub_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sub_1_b_ret{ + double r {0.0};r = x - y; + x_b += r_b; + y_b -= r_b; + r_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::sub_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sub_2_b_ret{ + double r {0.0};r = x - y - x; + x_b += r_b; + y_b -= r_b; + x_b -= r_b; + r_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::add_sub_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_sub_2_b_ret{ + double r {0.0};r = x + y - x; + x_b += r_b; + y_b += r_b; + x_b -= r_b; + r_b = 0.0; return r; } [[nodiscard]] auto ad_test_reverse::mul_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_1_b_ret{ double r {0.0};r = x * y; x_b += y * r_b; y_b += x * r_b; + r_b = 0.0; return r; } -#line 204 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::mul_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_2_b_ret{ + double r {0.0}; +auto temp_1_b {0.0}; + + auto temp_1 {x * y}; + r = temp_1 * x; + temp_1_b += x * r_b; + x_b += cpp2::move(temp_1) * r_b; + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::div_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> div_1_b_ret{ + double r {0.0};r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); + x_b += r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),y); + y_b -= x * r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),(y * y)); + r_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::div_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> div_2_b_ret{ + double r {0.0}; +auto temp_1_b {0.0}; + + auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; + r = temp_1 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(temp_1),y); + temp_1_b += r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),y); + y_b -= cpp2::move(temp_1) * r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),(y * y)); + r_b = 0.0; + x_b += temp_1_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(temp_1_b),y); + y_b -= x * temp_1_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(temp_1_b),(y * y)); + temp_1_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::mul_div_2_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_div_2_b_ret{ + double r {0.0}; +auto temp_1_b {0.0}; + + auto temp_1 {x * y}; + r = temp_1 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(temp_1),x); + temp_1_b += r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),x); + x_b -= cpp2::move(temp_1) * r_b / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(r_b),(x * x)); + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::mul_add_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> mul_add_b_ret{ + double r {0.0}; +double temp_1_b {0.0}; + + double temp_1 {x + y}; + r = x * temp_1; + x_b += cpp2::move(temp_1) * r_b; + temp_1_b += x * r_b; + r_b = 0.0; + x_b += temp_1_b; + y_b += temp_1_b; + temp_1_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::add_mul_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_mul_b_ret{ + double r {0.0}; +double temp_1_b {0.0}; + + double temp_1 {x * y}; + r = x + cpp2::move(temp_1); + x_b += r_b; + temp_1_b += r_b; + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; + return r; } + +#line 244 "pure2-autodiff.cpp2" } -#line 207 "pure2-autodiff.cpp2" +#line 247 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 208 "pure2-autodiff.cpp2" +#line 248 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -1138,19 +1398,20 @@ double temp_1_d2 {x_d * x_d2 + x * x_d_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 212 "pure2-autodiff.cpp2" +#line 252 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 216 "pure2-autodiff.cpp2" -auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, cpp2::impl::in r_b, auto const& ret) -> void{ +#line 256 "pure2-autodiff.cpp2" +auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void{ + r_b = 1.0; std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", y = " + cpp2::to_string(y) + ", r_b = " + cpp2::to_string(r_b) + ") = (r = " + cpp2::to_string(ret) + ", x_b = " + cpp2::to_string(x_b) + ", y_b = " + cpp2::to_string(y_b) + ")" << std::endl; x_b = 0.0; y_b = 0.0; } -#line 222 "pure2-autodiff.cpp2" +#line 263 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; @@ -1194,7 +1455,17 @@ auto main() -> int{ double w_b {1.0}; write_output_reverse("x + y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_1_b(x, x_b, y, y_b, w_b)); - write_output_reverse("x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_1_b(x, x_b, cpp2::move(y), y_b, w_b)); + write_output_reverse("x + y + x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x - y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sub_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x - y - x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sub_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + y - x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_sub_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y * x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x / y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::div_1_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x / y / y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::div_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * y / x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_div_2_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, cpp2::move(y), y_b, w_b)); static_cast(cpp2::move(x_b)); static_cast(cpp2::move(y_b)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index ace9227cc..96e23496c 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -902,6 +902,42 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = return; } + add_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y + x; + return; + } + + sub_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y; + return; + } + + sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x - y - x; + return; + } + + add_sub_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + y - x; + return; + } + mul_1:( in x: double, in y: double, @@ -911,6 +947,60 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = return; } + mul_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y * x; + return; + } + + div_1:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y; + return; + } + + div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x / y / y; + return; + } + + mul_div_2:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * y / x; + return; + } + + mul_add:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * (x + y); + return; + } + + add_mul:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x + x * y; + return; + } + add_1_b:( in x: double, inout x_b: double, @@ -922,6 +1012,70 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = r = x + y; x_b += r_b; y_b += r_b; + r_b = 0.0; + return; + } + + add_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x + y + x; + x_b += r_b; + y_b += r_b; + x_b += r_b; + r_b = 0.0; + return; + } + + sub_1_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x - y; + x_b += r_b; + y_b -= r_b; + r_b = 0.0; + return; + } + + sub_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x - y - x; + x_b += r_b; + y_b -= r_b; + x_b -= r_b; + r_b = 0.0; + return; + } + + add_sub_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x + y - x; + x_b += r_b; + y_b += r_b; + x_b -= r_b; + r_b = 0.0; return; } @@ -936,6 +1090,122 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = r = x * y; x_b += y * r_b; y_b += x * r_b; + r_b = 0.0; + return; + } + + mul_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: _ = 0.0; + temp_1: _ = x * y; + r = temp_1 * x; + temp_1_b += x * r_b; + x_b += temp_1 * r_b; + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; + return; + } + + div_1_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + r = x / y; + x_b += r_b / y; + y_b -= x * r_b / (y * y); + r_b = 0.0; + return; + } + + div_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: _ = 0.0; + temp_1: _ = x / y; + r = temp_1 / y; + temp_1_b += r_b / y; + y_b -= temp_1 * r_b / (y * y); + r_b = 0.0; + x_b += temp_1_b / y; + y_b -= x * temp_1_b / (y * y); + temp_1_b = 0.0; + return; + } + + mul_div_2_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: _ = 0.0; + temp_1: _ = x * y; + r = temp_1 / x; + temp_1_b += r_b / x; + x_b -= temp_1 * r_b / (x * x); + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; + return; + } + + mul_add_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: double = 0.0; + temp_1: double = x + y; + r = x * temp_1; + x_b += temp_1 * r_b; + temp_1_b += x * r_b; + r_b = 0.0; + x_b += temp_1_b; + y_b += temp_1_b; + temp_1_b = 0.0; + return; + } + + add_mul_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: double = 0.0; + temp_1: double = x * y; + r = x + temp_1; + x_b += r_b; + temp_1_b += r_b; + r_b = 0.0; + x_b += y * temp_1_b; + y_b += x * temp_1_b; + temp_1_b = 0.0; return; } } diff --git a/source/reflect.h b/source/reflect.h index 361304086..e4d3ce950 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -137,83 +137,83 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 5298 "reflect.h2" +#line 5301 "reflect.h2" class autodiff_stmt_handler; -#line 5593 "reflect.h2" +#line 5596 "reflect.h2" class autodiff_declaration_handler; -#line 5938 "reflect.h2" +#line 5941 "reflect.h2" class expression_flags; -#line 5954 "reflect.h2" +#line 5957 "reflect.h2" class regex_token; -#line 5981 "reflect.h2" +#line 5984 "reflect.h2" class regex_token_check; -#line 6002 "reflect.h2" +#line 6005 "reflect.h2" class regex_token_code; -#line 6023 "reflect.h2" +#line 6026 "reflect.h2" class regex_token_empty; -#line 6041 "reflect.h2" +#line 6044 "reflect.h2" class regex_token_list; -#line 6093 "reflect.h2" +#line 6096 "reflect.h2" class parse_context_group_state; -#line 6154 "reflect.h2" +#line 6157 "reflect.h2" class parse_context_branch_reset_state; -#line 6197 "reflect.h2" +#line 6200 "reflect.h2" class parse_context; -#line 6598 "reflect.h2" +#line 6601 "reflect.h2" class generation_function_context; -#line 6616 "reflect.h2" +#line 6619 "reflect.h2" class generation_context; -#line 6815 "reflect.h2" +#line 6818 "reflect.h2" class alternative_token; -#line 6830 "reflect.h2" +#line 6833 "reflect.h2" class alternative_token_gen; -#line 6895 "reflect.h2" +#line 6898 "reflect.h2" class any_token; -#line 6912 "reflect.h2" +#line 6915 "reflect.h2" class atomic_group_token; -#line 6942 "reflect.h2" +#line 6945 "reflect.h2" class char_token; -#line 7057 "reflect.h2" +#line 7060 "reflect.h2" class class_token; -#line 7281 "reflect.h2" +#line 7284 "reflect.h2" class group_ref_token; -#line 7418 "reflect.h2" +#line 7421 "reflect.h2" class group_token; -#line 7765 "reflect.h2" +#line 7768 "reflect.h2" class lookahead_lookbehind_token; -#line 7860 "reflect.h2" +#line 7863 "reflect.h2" class range_token; -#line 8017 "reflect.h2" +#line 8020 "reflect.h2" class special_range_token; -#line 8103 "reflect.h2" +#line 8106 "reflect.h2" template class regex_generator; -#line 8366 "reflect.h2" +#line 8369 "reflect.h2" } } @@ -1997,22 +1997,22 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand #line 4743 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4753 "reflect.h2" +#line 4754 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4759 "reflect.h2" +#line 4760 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4769 "reflect.h2" +#line 4772 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4778 "reflect.h2" +#line 4781 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -2022,176 +2022,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_rws_name(); -#line 4783 "reflect.h2" +#line 4786 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4794 "reflect.h2" +#line 4797 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4855 "reflect.h2" +#line 4858 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 5004 "reflect.h2" +#line 5007 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5039 "reflect.h2" +#line 5042 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5043 "reflect.h2" +#line 5046 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5047 "reflect.h2" +#line 5050 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5051 "reflect.h2" +#line 5054 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5055 "reflect.h2" +#line 5058 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5059 "reflect.h2" +#line 5062 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5063 "reflect.h2" +#line 5066 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5067 "reflect.h2" +#line 5070 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5071 "reflect.h2" +#line 5074 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5075 "reflect.h2" +#line 5078 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5079 "reflect.h2" +#line 5082 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5083 "reflect.h2" +#line 5086 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5114 "reflect.h2" +#line 5117 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5201 "reflect.h2" +#line 5204 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5205 "reflect.h2" +#line 5208 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5221 "reflect.h2" +#line 5224 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5261 "reflect.h2" +#line 5264 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5296 "reflect.h2" +#line 5299 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5302 "reflect.h2" +#line 5305 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5311 "reflect.h2" +#line 5314 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5316 "reflect.h2" +#line 5319 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5321 "reflect.h2" +#line 5324 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5372 "reflect.h2" +#line 5375 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5377 "reflect.h2" +#line 5380 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5382 "reflect.h2" +#line 5385 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5387 "reflect.h2" +#line 5390 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5395 "reflect.h2" +#line 5398 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5412 "reflect.h2" +#line 5415 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5462 "reflect.h2" +#line 5465 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5473 "reflect.h2" +#line 5476 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5477 "reflect.h2" +#line 5480 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5502 "reflect.h2" +#line 5505 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5506 "reflect.h2" +#line 5509 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5510 "reflect.h2" +#line 5513 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5514 "reflect.h2" +#line 5517 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5518 "reflect.h2" +#line 5521 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5522 "reflect.h2" +#line 5525 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5526 "reflect.h2" +#line 5529 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5530 "reflect.h2" +#line 5533 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5534 "reflect.h2" +#line 5537 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5538 "reflect.h2" +#line 5541 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5542 "reflect.h2" +#line 5545 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5546 "reflect.h2" +#line 5549 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5550 "reflect.h2" +#line 5553 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5555 "reflect.h2" +#line 5558 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5587 "reflect.h2" +#line 5590 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5591 "reflect.h2" +#line 5594 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5597 "reflect.h2" +#line 5600 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2201,37 +2201,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5609 "reflect.h2" +#line 5612 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5614 "reflect.h2" +#line 5617 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5772 "reflect.h2" +#line 5775 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5800 "reflect.h2" +#line 5803 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5824 "reflect.h2" +#line 5827 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5829 "reflect.h2" +#line 5832 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5832 "reflect.h2" +#line 5835 "reflect.h2" }; -#line 5835 "reflect.h2" +#line 5838 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5934 "reflect.h2" +#line 5937 "reflect.h2" using error_func = std::function x)>; -#line 5938 "reflect.h2" +#line 5941 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2266,20 +2266,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5946 "reflect.h2" +#line 5949 "reflect.h2" }; -#line 5954 "reflect.h2" +#line 5957 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5962 "reflect.h2" +#line 5965 "reflect.h2" public: explicit regex_token(); -#line 5967 "reflect.h2" +#line 5970 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2291,103 +2291,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5973 "reflect.h2" +#line 5976 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5979 "reflect.h2" +#line 5982 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5985 "reflect.h2" +#line 5988 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5992 "reflect.h2" +#line 5995 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5996 "reflect.h2" +#line 5999 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 5997 "reflect.h2" +#line 6000 "reflect.h2" }; -#line 6000 "reflect.h2" +#line 6003 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6006 "reflect.h2" +#line 6009 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6013 "reflect.h2" +#line 6016 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6017 "reflect.h2" +#line 6020 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6018 "reflect.h2" +#line 6021 "reflect.h2" }; -#line 6021 "reflect.h2" +#line 6024 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6027 "reflect.h2" +#line 6030 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6031 "reflect.h2" +#line 6034 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6035 "reflect.h2" +#line 6038 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6036 "reflect.h2" +#line 6039 "reflect.h2" }; -#line 6039 "reflect.h2" +#line 6042 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6045 "reflect.h2" +#line 6048 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6052 "reflect.h2" +#line 6055 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6058 "reflect.h2" +#line 6061 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6064 "reflect.h2" +#line 6067 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6072 "reflect.h2" +#line 6075 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2395,10 +2395,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6084 "reflect.h2" +#line 6087 "reflect.h2" }; -#line 6087 "reflect.h2" +#line 6090 "reflect.h2" // // Parse and generation context. // @@ -2414,33 +2414,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6107 "reflect.h2" +#line 6110 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6114 "reflect.h2" +#line 6117 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6126 "reflect.h2" +#line 6129 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6131 "reflect.h2" +#line 6134 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6135 "reflect.h2" +#line 6138 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6149 "reflect.h2" +#line 6152 "reflect.h2" }; -#line 6152 "reflect.h2" +#line 6155 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2453,25 +2453,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6170 "reflect.h2" +#line 6173 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6176 "reflect.h2" +#line 6179 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6183 "reflect.h2" +#line 6186 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6190 "reflect.h2" +#line 6193 "reflect.h2" }; -#line 6193 "reflect.h2" +#line 6196 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2487,7 +2487,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6209 "reflect.h2" +#line 6212 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2495,64 +2495,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6220 "reflect.h2" +#line 6223 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6233 "reflect.h2" +#line 6236 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6241 "reflect.h2" +#line 6244 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6245 "reflect.h2" +#line 6248 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6249 "reflect.h2" +#line 6252 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6261 "reflect.h2" +#line 6264 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6268 "reflect.h2" +#line 6271 "reflect.h2" public: auto next_alternative() & -> void; -#line 6274 "reflect.h2" +#line 6277 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6280 "reflect.h2" +#line 6283 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6284 "reflect.h2" +#line 6287 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6295 "reflect.h2" +#line 6298 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6299 "reflect.h2" +#line 6302 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6305 "reflect.h2" +#line 6308 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6309 "reflect.h2" +#line 6312 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6316 "reflect.h2" +#line 6319 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6327 "reflect.h2" +#line 6330 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2560,51 +2560,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6371 "reflect.h2" +#line 6374 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6383 "reflect.h2" +#line 6386 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6396 "reflect.h2" +#line 6399 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6419 "reflect.h2" +#line 6422 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6436 "reflect.h2" +#line 6439 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6457 "reflect.h2" +#line 6460 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6467 "reflect.h2" +#line 6470 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6471 "reflect.h2" +#line 6474 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6527 "reflect.h2" +#line 6530 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6566 "reflect.h2" +#line 6569 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6581 "reflect.h2" +#line 6584 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2616,10 +2616,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6592 "reflect.h2" +#line 6595 "reflect.h2" }; -#line 6595 "reflect.h2" +#line 6598 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2629,16 +2629,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6609 "reflect.h2" +#line 6612 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6612 "reflect.h2" +#line 6615 "reflect.h2" }; -#line 6615 "reflect.h2" +#line 6618 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2658,68 +2658,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6637 "reflect.h2" +#line 6640 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6643 "reflect.h2" +#line 6646 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6652 "reflect.h2" +#line 6655 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6663 "reflect.h2" +#line 6666 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6670 "reflect.h2" +#line 6673 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6690 "reflect.h2" +#line 6693 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6700 "reflect.h2" +#line 6703 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6723 "reflect.h2" +#line 6726 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6731 "reflect.h2" +#line 6734 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6735 "reflect.h2" +#line 6738 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6741 "reflect.h2" +#line 6744 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6747 "reflect.h2" +#line 6750 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6757 "reflect.h2" +#line 6760 "reflect.h2" public: auto finish_context() & -> void; -#line 6765 "reflect.h2" +#line 6768 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6771 "reflect.h2" +#line 6774 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6775 "reflect.h2" +#line 6778 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6779 "reflect.h2" +#line 6782 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6803 "reflect.h2" +#line 6806 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2727,7 +2727,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6809 "reflect.h2" +#line 6812 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2747,27 +2747,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6828 "reflect.h2" +#line 6831 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6834 "reflect.h2" +#line 6837 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6841 "reflect.h2" +#line 6844 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6858 "reflect.h2" +#line 6861 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6865 "reflect.h2" +#line 6868 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6878 "reflect.h2" +#line 6881 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2775,19 +2775,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6890 "reflect.h2" +#line 6893 "reflect.h2" }; -#line 6893 "reflect.h2" +#line 6896 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6899 "reflect.h2" +#line 6902 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6903 "reflect.h2" +#line 6906 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2795,7 +2795,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6908 "reflect.h2" +#line 6911 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2803,17 +2803,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6916 "reflect.h2" +#line 6919 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6927 "reflect.h2" +#line 6930 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6935 "reflect.h2" +#line 6938 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2821,7 +2821,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6938 "reflect.h2" +#line 6941 "reflect.h2" }; // Regex syntax: a @@ -2829,34 +2829,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6946 "reflect.h2" +#line 6949 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6955 "reflect.h2" +#line 6958 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6961 "reflect.h2" +#line 6964 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6965 "reflect.h2" +#line 6968 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6988 "reflect.h2" +#line 6991 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7009 "reflect.h2" +#line 7012 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7027 "reflect.h2" +#line 7030 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7042 "reflect.h2" +#line 7045 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7048 "reflect.h2" +#line 7051 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2864,33 +2864,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7052 "reflect.h2" +#line 7055 "reflect.h2" }; -#line 7055 "reflect.h2" +#line 7058 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7061 "reflect.h2" +#line 7064 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7073 "reflect.h2" +#line 7076 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7199 "reflect.h2" +#line 7202 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7208 "reflect.h2" +#line 7211 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7213 "reflect.h2" +#line 7216 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2898,20 +2898,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7220 "reflect.h2" +#line 7223 "reflect.h2" }; -#line 7223 "reflect.h2" +#line 7226 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7264 "reflect.h2" +#line 7267 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7275 "reflect.h2" +#line 7278 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2921,20 +2921,20 @@ class class_token class group_ref_token : public regex_token { -#line 7285 "reflect.h2" +#line 7288 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7297 "reflect.h2" +#line 7300 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7398 "reflect.h2" +#line 7401 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7402 "reflect.h2" +#line 7405 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2942,10 +2942,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7405 "reflect.h2" +#line 7408 "reflect.h2" }; -#line 7408 "reflect.h2" +#line 7411 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2959,29 +2959,29 @@ class group_ref_token class group_token : public regex_token { -#line 7422 "reflect.h2" +#line 7425 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7444 "reflect.h2" +#line 7447 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7458 "reflect.h2" +#line 7461 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7617 "reflect.h2" +#line 7620 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7625 "reflect.h2" +#line 7628 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7643 "reflect.h2" +#line 7646 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7674 "reflect.h2" +#line 7677 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2990,25 +2990,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7681 "reflect.h2" +#line 7684 "reflect.h2" }; -#line 7684 "reflect.h2" +#line 7687 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7725 "reflect.h2" +#line 7728 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7745 "reflect.h2" +#line 7748 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7761 "reflect.h2" +#line 7764 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3016,20 +3016,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7769 "reflect.h2" +#line 7772 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7778 "reflect.h2" +#line 7781 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7789 "reflect.h2" +#line 7792 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7796 "reflect.h2" +#line 7799 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3037,26 +3037,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7799 "reflect.h2" +#line 7802 "reflect.h2" }; -#line 7802 "reflect.h2" +#line 7805 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7830 "reflect.h2" +#line 7833 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7858 "reflect.h2" +#line 7861 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7864 "reflect.h2" +#line 7867 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3066,22 +3066,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7944 "reflect.h2" +#line 7947 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7956 "reflect.h2" +#line 7959 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7969 "reflect.h2" +#line 7972 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7988 "reflect.h2" +#line 7991 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7998 "reflect.h2" +#line 8001 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8009 "reflect.h2" +#line 8012 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3089,16 +3089,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8012 "reflect.h2" +#line 8015 "reflect.h2" }; -#line 8015 "reflect.h2" +#line 8018 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8021 "reflect.h2" +#line 8024 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3107,7 +3107,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8051 "reflect.h2" +#line 8054 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3116,14 +3116,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8073 "reflect.h2" +#line 8076 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8095 "reflect.h2" +#line 8098 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3144,24 +3144,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8118 "reflect.h2" +#line 8121 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8153 "reflect.h2" +#line 8156 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8167 "reflect.h2" +#line 8170 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8179 "reflect.h2" +#line 8182 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8234 "reflect.h2" +#line 8237 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3172,7 +3172,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8366 "reflect.h2" +#line 8369 "reflect.h2" } } @@ -8434,7 +8434,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar #line 4559 "reflect.h2" auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} #line 4560 "reflect.h2" - auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop += v; }} + auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop = v + rws_backprop; }} #line 4562 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ @@ -8643,16 +8643,17 @@ auto i{0}; CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); } CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4753 "reflect.h2" +#line 4754 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4755 "reflect.h2" +#line 4756 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4759 "reflect.h2" +#line 4760 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8660,16 +8661,18 @@ auto i{0}; if (CPP2_UFCS(is_taylor)((*cpp2::impl::assert_not_null(ctx)))) { CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); } + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs_b) + " : " + cpp2::to_string(type_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4769 "reflect.h2" +#line 4772 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4771 "reflect.h2" +#line 4774 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4773 "reflect.h2" +#line 4776 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } @@ -8681,7 +8684,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8691,7 +8694,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4794 "reflect.h2" +#line 4797 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8753,7 +8756,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} }} } -#line 4855 "reflect.h2" +#line 4858 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8761,7 +8764,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4861 "reflect.h2" +#line 4864 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8775,7 +8778,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4873 "reflect.h2" +#line 4876 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8798,7 +8801,7 @@ auto i{0}; { auto i{0}; -#line 4894 "reflect.h2" +#line 4897 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8823,7 +8826,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4917 "reflect.h2" +#line 4920 "reflect.h2" if (handle_special_function(object, object_d, function_name, args)) { return ; } @@ -8911,7 +8914,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 5004 "reflect.h2" +#line 5007 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8934,7 +8937,7 @@ auto i{0}; { auto i{1}; -#line 5025 "reflect.h2" +#line 5028 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8944,69 +8947,69 @@ auto i{1}; } } -#line 5033 "reflect.h2" +#line 5036 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); return true; } -#line 5039 "reflect.h2" +#line 5042 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5043 "reflect.h2" +#line 5046 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5047 "reflect.h2" +#line 5050 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5051 "reflect.h2" +#line 5054 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5055 "reflect.h2" +#line 5058 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5059 "reflect.h2" +#line 5062 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5063 "reflect.h2" +#line 5066 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5067 "reflect.h2" +#line 5070 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5071 "reflect.h2" +#line 5074 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5075 "reflect.h2" +#line 5078 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5079 "reflect.h2" +#line 5082 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5083 "reflect.h2" +#line 5086 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9038,7 +9041,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5114 "reflect.h2" +#line 5117 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9109,7 +9112,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5185 "reflect.h2" +#line 5188 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9126,12 +9129,12 @@ auto i{1}; } } -#line 5201 "reflect.h2" +#line 5204 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5205 "reflect.h2" +#line 5208 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9148,7 +9151,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5221 "reflect.h2" +#line 5224 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9157,7 +9160,7 @@ auto i{1}; { auto i{0}; -#line 5228 "reflect.h2" +#line 5231 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9172,7 +9175,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5241 "reflect.h2" +#line 5244 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9193,7 +9196,7 @@ auto i{0}; } } -#line 5261 "reflect.h2" +#line 5264 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9230,26 +9233,26 @@ auto i{0}; }}}} } -#line 5306 "reflect.h2" +#line 5309 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5309 "reflect.h2" +#line 5312 "reflect.h2" } -#line 5311 "reflect.h2" +#line 5314 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5316 "reflect.h2" +#line 5319 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5321 "reflect.h2" +#line 5324 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9300,22 +9303,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5372 "reflect.h2" +#line 5375 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5377 "reflect.h2" +#line 5380 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5382 "reflect.h2" +#line 5385 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5387 "reflect.h2" +#line 5390 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -9323,7 +9326,7 @@ auto i{0}; diff += "}\n"; } -#line 5395 "reflect.h2" +#line 5398 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9340,7 +9343,7 @@ auto i{0}; } } -#line 5412 "reflect.h2" +#line 5415 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -9390,7 +9393,7 @@ auto i{0}; }} } -#line 5462 "reflect.h2" +#line 5465 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9402,12 +9405,12 @@ auto i{0}; } } -#line 5473 "reflect.h2" +#line 5476 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5477 "reflect.h2" +#line 5480 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9433,73 +9436,73 @@ auto i{0}; } } -#line 5502 "reflect.h2" +#line 5505 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5506 "reflect.h2" +#line 5509 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5510 "reflect.h2" +#line 5513 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5514 "reflect.h2" +#line 5517 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5518 "reflect.h2" +#line 5521 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5522 "reflect.h2" +#line 5525 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5526 "reflect.h2" +#line 5529 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5530 "reflect.h2" +#line 5533 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5534 "reflect.h2" +#line 5537 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5538 "reflect.h2" +#line 5541 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5542 "reflect.h2" +#line 5545 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5546 "reflect.h2" +#line 5549 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5550 "reflect.h2" +#line 5553 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5555 "reflect.h2" +#line 5558 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9508,7 +9511,7 @@ auto i{0}; { auto i{0}; -#line 5562 "reflect.h2" +#line 5565 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9523,7 +9526,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5575 "reflect.h2" +#line 5578 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9536,27 +9539,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5587 "reflect.h2" +#line 5590 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5604 "reflect.h2" +#line 5607 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5607 "reflect.h2" +#line 5610 "reflect.h2" } -#line 5609 "reflect.h2" +#line 5612 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5614 "reflect.h2" +#line 5617 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9686,10 +9689,10 @@ auto i{0}; return ; } -#line 5744 "reflect.h2" +#line 5747 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5747 "reflect.h2" +#line 5750 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9714,7 +9717,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5772 "reflect.h2" +#line 5775 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9742,7 +9745,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5800 "reflect.h2" +#line 5803 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9766,17 +9769,17 @@ auto i{0}; } } -#line 5824 "reflect.h2" +#line 5827 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5829 "reflect.h2" +#line 5832 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5835 "reflect.h2" +#line 5838 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9952,7 +9955,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5920 "reflect.h2" +#line 5923 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9968,11 +9971,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5936 "reflect.h2" +#line 5939 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5940 "reflect.h2" +#line 5943 "reflect.h2" // mod: i // mod: m // mod: s @@ -9980,116 +9983,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5949 "reflect.h2" +#line 5952 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5958 "reflect.h2" +#line 5961 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5960 "reflect.h2" +#line 5963 "reflect.h2" } -#line 5962 "reflect.h2" +#line 5965 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5964 "reflect.h2" +#line 5967 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5970 "reflect.h2" +#line 5973 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5971 "reflect.h2" +#line 5974 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5972 "reflect.h2" +#line 5975 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5987 "reflect.h2" +#line 5990 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5990 "reflect.h2" +#line 5993 "reflect.h2" } -#line 5992 "reflect.h2" +#line 5995 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5996 "reflect.h2" +#line 5999 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6008 "reflect.h2" +#line 6011 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6011 "reflect.h2" +#line 6014 "reflect.h2" } -#line 6013 "reflect.h2" +#line 6016 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6017 "reflect.h2" +#line 6020 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6027 "reflect.h2" +#line 6030 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6029 "reflect.h2" +#line 6032 "reflect.h2" } -#line 6031 "reflect.h2" +#line 6034 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6035 "reflect.h2" +#line 6038 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6047 "reflect.h2" +#line 6050 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6050 "reflect.h2" +#line 6053 "reflect.h2" } -#line 6052 "reflect.h2" +#line 6055 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6058 "reflect.h2" +#line 6061 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6064 "reflect.h2" +#line 6067 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10098,7 +10101,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6072 "reflect.h2" +#line 6075 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10114,7 +10117,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6100 "reflect.h2" +#line 6103 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10122,14 +10125,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6108 "reflect.h2" +#line 6111 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6115 "reflect.h2" +#line 6118 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10141,15 +10144,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6127 "reflect.h2" +#line 6130 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6132 "reflect.h2" +#line 6135 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6136 "reflect.h2" +#line 6139 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10170,7 +10173,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6162 "reflect.h2" +#line 6165 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10179,20 +10182,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6171 "reflect.h2" +#line 6174 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6177 "reflect.h2" +#line 6180 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6184 "reflect.h2" +#line 6187 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10207,16 +10210,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6214 "reflect.h2" +#line 6217 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6218 "reflect.h2" +#line 6221 "reflect.h2" } -#line 6224 "reflect.h2" +#line 6227 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10226,7 +10229,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6234 "reflect.h2" +#line 6237 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10234,17 +10237,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6241 "reflect.h2" +#line 6244 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6245 "reflect.h2" +#line 6248 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6252 "reflect.h2" +#line 6255 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10254,7 +10257,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6261 "reflect.h2" +#line 6264 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10262,24 +10265,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6268 "reflect.h2" +#line 6271 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6276 "reflect.h2" +#line 6279 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6280 "reflect.h2" +#line 6283 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6284 "reflect.h2" +#line 6287 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10291,22 +10294,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6295 "reflect.h2" +#line 6298 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6301 "reflect.h2" +#line 6304 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6305 "reflect.h2" +#line 6308 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6309 "reflect.h2" +#line 6312 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10314,7 +10317,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6316 "reflect.h2" +#line 6319 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10326,10 +10329,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6329 "reflect.h2" +#line 6332 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6332 "reflect.h2" +#line 6335 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10369,7 +10372,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6372 "reflect.h2" +#line 6375 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10381,14 +10384,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6383 "reflect.h2" +#line 6386 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6384 "reflect.h2" +#line 6387 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6385 "reflect.h2" +#line 6388 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6387 "reflect.h2" +#line 6390 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10398,10 +10401,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6396 "reflect.h2" +#line 6399 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6398 "reflect.h2" +#line 6401 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10423,14 +10426,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6419 "reflect.h2" +#line 6422 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6420 "reflect.h2" +#line 6423 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6421 "reflect.h2" +#line 6424 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6423 "reflect.h2" +#line 6426 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10444,7 +10447,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6436 "reflect.h2" +#line 6439 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10466,7 +10469,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6457 "reflect.h2" +#line 6460 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10477,12 +10480,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6467 "reflect.h2" +#line 6470 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6468 "reflect.h2" +#line 6471 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6473 "reflect.h2" +#line 6476 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10537,7 +10540,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6527 "reflect.h2" +#line 6530 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10577,7 +10580,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6566 "reflect.h2" +#line 6569 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10593,21 +10596,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6583 "reflect.h2" +#line 6586 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6584 "reflect.h2" +#line 6587 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6585 "reflect.h2" +#line 6588 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6587 "reflect.h2" +#line 6590 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6602 "reflect.h2" +#line 6605 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10615,7 +10618,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6609 "reflect.h2" +#line 6612 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10625,22 +10628,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6627 "reflect.h2" +#line 6630 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6632 "reflect.h2" +#line 6635 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6638 "reflect.h2" +#line 6641 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6644 "reflect.h2" +#line 6647 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10649,7 +10652,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6652 "reflect.h2" +#line 6655 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10661,7 +10664,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6663 "reflect.h2" +#line 6666 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10669,7 +10672,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6670 "reflect.h2" +#line 6673 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10690,7 +10693,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6691 "reflect.h2" +#line 6694 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10700,7 +10703,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6701 "reflect.h2" +#line 6704 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10723,33 +10726,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6725 "reflect.h2" +#line 6728 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6731 "reflect.h2" +#line 6734 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6735 "reflect.h2" +#line 6738 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6741 "reflect.h2" +#line 6744 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6749 "reflect.h2" +#line 6752 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10758,7 +10761,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6757 "reflect.h2" +#line 6760 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10767,22 +10770,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6767 "reflect.h2" +#line 6770 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6771 "reflect.h2" +#line 6774 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6775 "reflect.h2" +#line 6778 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6779 "reflect.h2" +#line 6782 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10806,18 +10809,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6804 "reflect.h2" +#line 6807 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6819 "reflect.h2" +#line 6822 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6821 "reflect.h2" +#line 6824 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10828,15 +10831,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6836 "reflect.h2" +#line 6839 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6839 "reflect.h2" +#line 6842 "reflect.h2" } -#line 6841 "reflect.h2" +#line 6844 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10854,7 +10857,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6858 "reflect.h2" +#line 6861 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10862,7 +10865,7 @@ generation_function_context::generation_function_context(){} } } -#line 6865 "reflect.h2" +#line 6868 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10876,7 +10879,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6878 "reflect.h2" +#line 6881 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10892,14 +10895,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6899 "reflect.h2" +#line 6902 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6901 "reflect.h2" +#line 6904 "reflect.h2" } -#line 6903 "reflect.h2" +#line 6906 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10908,11 +10911,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6918 "reflect.h2" +#line 6921 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6920 "reflect.h2" +#line 6923 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10920,7 +10923,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6927 "reflect.h2" +#line 6930 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10929,37 +10932,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6935 "reflect.h2" +#line 6938 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6949 "reflect.h2" +#line 6952 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6953 "reflect.h2" +#line 6956 "reflect.h2" } -#line 6955 "reflect.h2" +#line 6958 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6959 "reflect.h2" +#line 6962 "reflect.h2" } -#line 6961 "reflect.h2" +#line 6964 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6965 "reflect.h2" +#line 6968 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10968,14 +10971,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6971 "reflect.h2" +#line 6974 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6976 "reflect.h2" +#line 6979 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10988,7 +10991,7 @@ size_t i{0}; } } -#line 6988 "reflect.h2" +#line 6991 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11010,7 +11013,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7009 "reflect.h2" +#line 7012 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11029,7 +11032,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7027 "reflect.h2" +#line 7030 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11045,14 +11048,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7042 "reflect.h2" +#line 7045 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7048 "reflect.h2" +#line 7051 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11060,19 +11063,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7065 "reflect.h2" +#line 7068 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7066 "reflect.h2" +#line 7069 "reflect.h2" { -#line 7071 "reflect.h2" +#line 7074 "reflect.h2" } -#line 7074 "reflect.h2" +#line 7077 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11198,7 +11201,7 @@ size_t i{0}; ); } -#line 7199 "reflect.h2" +#line 7202 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11208,13 +11211,13 @@ size_t i{0}; ); } -#line 7208 "reflect.h2" +#line 7211 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7213 "reflect.h2" +#line 7216 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11225,12 +11228,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7225 "reflect.h2" +#line 7228 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7230 "reflect.h2" +#line 7233 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11264,7 +11267,7 @@ size_t i{0}; } -#line 7266 "reflect.h2" +#line 7269 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11273,19 +11276,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7289 "reflect.h2" +#line 7292 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7290 "reflect.h2" +#line 7293 "reflect.h2" { -#line 7295 "reflect.h2" +#line 7298 "reflect.h2" } -#line 7297 "reflect.h2" +#line 7300 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11387,19 +11390,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7398 "reflect.h2" +#line 7401 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7402 "reflect.h2" +#line 7405 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7426 "reflect.h2" +#line 7429 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11418,7 +11421,7 @@ size_t i{0}; return r; } -#line 7444 "reflect.h2" +#line 7447 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11433,7 +11436,7 @@ size_t i{0}; return r; } -#line 7458 "reflect.h2" +#line 7461 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11593,7 +11596,7 @@ size_t i{0}; } } -#line 7617 "reflect.h2" +#line 7620 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11602,7 +11605,7 @@ size_t i{0}; return r; } -#line 7625 "reflect.h2" +#line 7628 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11621,7 +11624,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7643 "reflect.h2" +#line 7646 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11653,7 +11656,7 @@ size_t i{0}; } } -#line 7674 "reflect.h2" +#line 7677 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11664,7 +11667,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7686 "reflect.h2" +#line 7689 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11703,7 +11706,7 @@ size_t i{0}; return r; } -#line 7727 "reflect.h2" +#line 7730 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11721,7 +11724,7 @@ size_t i{0}; }} } -#line 7747 "reflect.h2" +#line 7750 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11735,16 +11738,16 @@ size_t i{0}; } } -#line 7773 "reflect.h2" +#line 7776 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7776 "reflect.h2" +#line 7779 "reflect.h2" } -#line 7778 "reflect.h2" +#line 7781 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11756,7 +11759,7 @@ size_t i{0}; } } -#line 7789 "reflect.h2" +#line 7792 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11764,14 +11767,14 @@ size_t i{0}; return r; } -#line 7796 "reflect.h2" +#line 7799 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7804 "reflect.h2" +#line 7807 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11797,7 +11800,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7832 "reflect.h2" +#line 7835 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11823,11 +11826,11 @@ size_t i{0}; return r; } -#line 7869 "reflect.h2" +#line 7872 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7871 "reflect.h2" +#line 7874 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11901,7 +11904,7 @@ size_t i{0}; return nullptr; } -#line 7944 "reflect.h2" +#line 7947 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11914,7 +11917,7 @@ size_t i{0}; }} } -#line 7956 "reflect.h2" +#line 7959 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11928,7 +11931,7 @@ size_t i{0}; }} } -#line 7969 "reflect.h2" +#line 7972 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11948,7 +11951,7 @@ size_t i{0}; return r; } -#line 7988 "reflect.h2" +#line 7991 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11959,7 +11962,7 @@ size_t i{0}; return r; } -#line 7998 "reflect.h2" +#line 8001 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11971,14 +11974,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8009 "reflect.h2" +#line 8012 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8021 "reflect.h2" +#line 8024 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12002,7 +12005,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8045 "reflect.h2" +#line 8048 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12012,7 +12015,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8057 "reflect.h2" +#line 8060 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12028,7 +12031,7 @@ size_t i{0}; } } -#line 8077 "reflect.h2" +#line 8080 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12046,15 +12049,15 @@ size_t i{0}; }} } -#line 8113 "reflect.h2" +#line 8116 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8116 "reflect.h2" +#line 8119 "reflect.h2" } -#line 8118 "reflect.h2" +#line 8121 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12090,7 +12093,7 @@ size_t i{0}; return source; } -#line 8153 "reflect.h2" +#line 8156 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12106,7 +12109,7 @@ size_t i{0}; } } -#line 8169 "reflect.h2" +#line 8172 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12115,7 +12118,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12170,7 +12173,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8238 "reflect.h2" +#line 8241 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12298,7 +12301,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8366 "reflect.h2" +#line 8369 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 90ff18747..a0dec8f6a 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4557,7 +4557,7 @@ autodiff_diff_code: type = { add_forward : (inout this, v: std::string) = { if ctx*.is_forward() { fwd += v; }} add_reverse_primal : (inout this, v: std::string) = { if ctx*.is_reverse() { rws_primal += v; }} - add_reverse_backprop: (inout this, v: std::string) = { if ctx*.is_reverse() { rws_backprop += v; }} + add_reverse_backprop: (inout this, v: std::string) = { if ctx*.is_reverse() { rws_backprop = v + rws_backprop; }} reset: (inout this) = { fwd = ""; @@ -4748,6 +4748,7 @@ autodiff_expression_handler: type = { diff.add_reverse_primal("(lhs_d)$ = (rhs_d)$;\n"); } diff.add_reverse_primal("(lhs)$ = (rhs)$;\n"); + diff.add_reverse_backprop("(lhs_b)$ = 0.0;\n"); diff.add_reverse_backprop(prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string) @@ -4763,7 +4764,9 @@ autodiff_expression_handler: type = { if ctx*.is_taylor() { diff.add_reverse_primal("(lhs_d)$: (type_d)$ = (rhs_d)$;\n"); } + diff.add_reverse_primal("(lhs_b)$ : (type_b)$ = 0.0;\n"); diff.add_reverse_primal("(lhs)$ : (type)$ = (rhs)$;\n"); + diff.add_reverse_backprop("(lhs_b)$ = 0.0;\n"); diff.add_reverse_backprop(prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } gen_declaration: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string, type: std::string) From 389854816bd0419804e17d9eeab7ed9b27e9bc8b Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 29 Aug 2025 09:41:20 +0200 Subject: [PATCH 47/54] Handling of special functions for reverse mode. --- regression-tests/pure2-autodiff.cpp2 | 5 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 1 + .../test-results/pure2-autodiff.cpp | 55 +- .../test-results/pure2-autodiff.cpp2.output | 28 + source/reflect.h | 1448 +++++++++-------- source/reflect.h2 | 42 +- 6 files changed, 858 insertions(+), 721 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 651c519f2..2e94dfcae 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -240,6 +240,10 @@ ad_test_reverse: @autodiff<"reverse"> @print type = { add_mul: (x: double, y: double) -> (r: double) = { r = x + x * y; } + + sin_call: (x: double, y: double) -> (r: double) = { + r = sin(x - y); + } } } @@ -314,6 +318,7 @@ main: () = { write_output_reverse("x * y / x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_div_2_b(x, x_b, y, y_b, w_b)); write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, y, y_b, w_b)); + write_output_reverse("sin(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sin_call_b(x, x_b, y, y_b, w_b)); _ = x_b; _ = y_b; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index 3d604f730..e243e4449 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -40,4 +40,5 @@ diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) +diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index bd9cec6c5..c4a639711 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -21,7 +21,7 @@ class ad_test; #line 194 "pure2-autodiff.cpp2" class ad_test_reverse; -#line 244 "pure2-autodiff.cpp2" +#line 248 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -416,6 +416,11 @@ using add_mul_ret = double; #line 240 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; +using sin_call_ret = double; + + +#line 244 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using add_1_b_ret = double; public: [[nodiscard]] static auto add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret; @@ -453,19 +458,22 @@ public: [[nodiscard]] static auto mul_add_b(cpp2::impl::in x, double& x_ using add_mul_b_ret = double; public: [[nodiscard]] static auto add_mul_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_mul_b_ret; +using sin_call_b_ret = double; +public: [[nodiscard]] static auto sin_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sin_call_b_ret; + public: ad_test_reverse() = default; public: ad_test_reverse(ad_test_reverse const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test_reverse const&) -> void = delete; -#line 243 "pure2-autodiff.cpp2" +#line 247 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 247 "pure2-autodiff.cpp2" +#line 251 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -485,15 +493,15 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 250 "pure2-autodiff.cpp2" +#line 254 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 256 "pure2-autodiff.cpp2" +#line 260 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void; -#line 263 "pure2-autodiff.cpp2" +#line 267 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -1233,6 +1241,13 @@ type_outer_d t_d {}; r.construct(x + x * y); return std::move(r.value()); } +#line 244 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ + cpp2::impl::deferred_init r; +#line 245 "pure2-autodiff.cpp2" + r.construct(sin(x - y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test_reverse::add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret{ double r {0.0};r = x + y; x_b += r_b; @@ -1355,13 +1370,26 @@ double temp_1_b {0.0}; temp_1_b = 0.0; return r; } -#line 244 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::sin_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sin_call_b_ret{ + double r {0.0}; +double temp_1_b {0.0}; + + double temp_1 {x - y}; + r = sin(temp_1); + temp_1_b += cos(cpp2::move(temp_1)) * r_b; + r_b = 0.0; + x_b += temp_1_b; + y_b -= temp_1_b; + temp_1_b = 0.0; + return r; } + +#line 248 "pure2-autodiff.cpp2" } -#line 247 "pure2-autodiff.cpp2" +#line 251 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 248 "pure2-autodiff.cpp2" +#line 252 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -1398,12 +1426,12 @@ double temp_1_d2 {x_d * x_d2 + x * x_d_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 252 "pure2-autodiff.cpp2" +#line 256 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 256 "pure2-autodiff.cpp2" +#line 260 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void{ r_b = 1.0; std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", y = " + cpp2::to_string(y) + ", r_b = " + cpp2::to_string(r_b) + ") = (r = " + cpp2::to_string(ret) + ", x_b = " + cpp2::to_string(x_b) + ", y_b = " + cpp2::to_string(y_b) + ")" << std::endl; @@ -1411,7 +1439,7 @@ auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in int{ double x {2.0}; @@ -1465,7 +1493,8 @@ auto main() -> int{ write_output_reverse("x / y / y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::div_2_b(x, x_b, y, y_b, w_b)); write_output_reverse("x * y / x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_div_2_b(x, x_b, y, y_b, w_b)); write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); - write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, cpp2::move(y), y_b, w_b)); + write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, y, y_b, w_b)); + write_output_reverse("sin(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sin_call_b(x, x_b, cpp2::move(y), y_b, w_b)); static_cast(cpp2::move(x_b)); static_cast(cpp2::move(y_b)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 96e23496c..d6093d901 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -1001,6 +1001,15 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = return; } + sin_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = sin(x - y); + return; + } + add_1_b:( in x: double, inout x_b: double, @@ -1208,6 +1217,25 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = temp_1_b = 0.0; return; } + + sin_call_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_1_b: double = 0.0; + temp_1: double = x - y; + r = sin(temp_1); + temp_1_b += cos(temp_1) * r_b; + r_b = 0.0; + x_b += temp_1_b; + y_b -= temp_1_b; + temp_1_b = 0.0; + return; + } } diff --git a/source/reflect.h b/source/reflect.h index e4d3ce950..2dcb74b96 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -111,109 +111,109 @@ class simple_traverser; #line 4091 "reflect.h2" class autodiff_special_func; -#line 4127 "reflect.h2" +#line 4135 "reflect.h2" class autodiff_declared_variable; -#line 4145 "reflect.h2" +#line 4153 "reflect.h2" class autodiff_declaration_stack_item; -#line 4184 "reflect.h2" +#line 4192 "reflect.h2" class autodiff_context; -#line 4547 "reflect.h2" +#line 4567 "reflect.h2" class autodiff_diff_code; -#line 4595 "reflect.h2" +#line 4615 "reflect.h2" class autodiff_activity_check; -#line 4693 "reflect.h2" +#line 4713 "reflect.h2" class autodiff_handler_base; -#line 4711 "reflect.h2" +#line 4731 "reflect.h2" class autodiff_expression_handler; -#line 5301 "reflect.h2" +#line 5333 "reflect.h2" class autodiff_stmt_handler; -#line 5596 "reflect.h2" +#line 5628 "reflect.h2" class autodiff_declaration_handler; -#line 5941 "reflect.h2" +#line 5973 "reflect.h2" class expression_flags; -#line 5957 "reflect.h2" +#line 5989 "reflect.h2" class regex_token; -#line 5984 "reflect.h2" +#line 6016 "reflect.h2" class regex_token_check; -#line 6005 "reflect.h2" +#line 6037 "reflect.h2" class regex_token_code; -#line 6026 "reflect.h2" +#line 6058 "reflect.h2" class regex_token_empty; -#line 6044 "reflect.h2" +#line 6076 "reflect.h2" class regex_token_list; -#line 6096 "reflect.h2" +#line 6128 "reflect.h2" class parse_context_group_state; -#line 6157 "reflect.h2" +#line 6189 "reflect.h2" class parse_context_branch_reset_state; -#line 6200 "reflect.h2" +#line 6232 "reflect.h2" class parse_context; -#line 6601 "reflect.h2" +#line 6633 "reflect.h2" class generation_function_context; -#line 6619 "reflect.h2" +#line 6651 "reflect.h2" class generation_context; -#line 6818 "reflect.h2" +#line 6850 "reflect.h2" class alternative_token; -#line 6833 "reflect.h2" +#line 6865 "reflect.h2" class alternative_token_gen; -#line 6898 "reflect.h2" +#line 6930 "reflect.h2" class any_token; -#line 6915 "reflect.h2" +#line 6947 "reflect.h2" class atomic_group_token; -#line 6945 "reflect.h2" +#line 6977 "reflect.h2" class char_token; -#line 7060 "reflect.h2" +#line 7092 "reflect.h2" class class_token; -#line 7284 "reflect.h2" +#line 7316 "reflect.h2" class group_ref_token; -#line 7421 "reflect.h2" +#line 7453 "reflect.h2" class group_token; -#line 7768 "reflect.h2" +#line 7800 "reflect.h2" class lookahead_lookbehind_token; -#line 7863 "reflect.h2" +#line 7895 "reflect.h2" class range_token; -#line 8020 "reflect.h2" +#line 8052 "reflect.h2" class special_range_token; -#line 8106 "reflect.h2" +#line 8138 "reflect.h2" template class regex_generator; -#line 8369 "reflect.h2" +#line 8401 "reflect.h2" } } @@ -1691,24 +1691,27 @@ class autodiff_special_func { public: std::string code_primal; public: std::string code_fwd; + public: std::string code_rws; public: std::string code_primal_higher_order; public: std::string code_fwd_higher_order; + public: std::string code_rws_higher_order; public: autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in is_member_, cpp2::impl::in code_primal_ = "", cpp2::impl::in code_fwd_ = "", - cpp2::impl::in code_primal_higher_order_ = "", cpp2::impl::in code_fwd_higher_order_ = ""); + cpp2::impl::in code_rws_ = "", cpp2::impl::in code_primal_higher_order_ = "", cpp2::impl::in code_fwd_higher_order_ = "", + cpp2::impl::in code_rws_higher_order_ = ""); -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" public: autodiff_special_func(autodiff_special_func const& that); -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" public: auto operator=(autodiff_special_func const& that) -> autodiff_special_func& ; -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" public: autodiff_special_func(autodiff_special_func&& that) noexcept; -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" public: auto operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& ; public: [[nodiscard]] auto is_match(cpp2::impl::in o) const& -> bool; -#line 4125 "reflect.h2" +#line 4133 "reflect.h2" }; class autodiff_declared_variable { @@ -1721,13 +1724,13 @@ class autodiff_declared_variable { public: autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_active_, cpp2::impl::in is_member_); -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" public: autodiff_declared_variable(autodiff_declared_variable const& that); -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" public: auto operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& ; -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" public: autodiff_declared_variable(autodiff_declared_variable&& that) noexcept; -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" public: auto operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& ; }; @@ -1744,62 +1747,71 @@ class autodiff_declaration_stack_item { using lookup_declaration_ret = std::vector; -#line 4159 "reflect.h2" +#line 4167 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret; struct lookup_variable_declaration_ret { bool found; autodiff_declared_variable r; }; -#line 4169 "reflect.h2" +#line 4177 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret; public: autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that); public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4182 "reflect.h2" +#line 4190 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4194 "reflect.h2" +#line 4202 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, false, "sin(_a1_)", "cos(_a1_) * _ad1_", + "_ab1_ += cos(_a1_) * _rb_;\n", "sin(_a1_)", - "_ad1_.sin(_a1_)" + "_ad1_.sin(_a1_)", + "TODO" ), autodiff_special_func("cos", 1, false, "cos(_a1_)", "-sin(_a1_) * _ad1_", + "_ab1_ += -sin(_a1_) * _rb_;\n", "cos(_a1_)", - "_ad1_.cos(_a1_)" + "_ad1_.cos(_a1_)", + "TODO" ), autodiff_special_func("exp", 1, false, "exp(_a1_)", "exp(_a1_) * _ad1_", + "_ab1_ += exp(_a1_) * _rb_;\n", "exp(_a1_)", - "_ad1_.exp(_a1_)" + "_ad1_.exp(_a1_)", + "TODO" ), autodiff_special_func("sqrt", 1, false, "sqrt(_a1_)", "0.5 * _ad1_ / sqrt(_a1_)", + "_ab1_ += 0.5 * _rb_ / sqrt(_a1_);\n", "sqrt(_a1_)", - "_ad1_.sqrt(_a1_)" + "_ad1_.sqrt(_a1_)", + "TODO" ), autodiff_special_func("push_back", 1, true, "_o_.push_back(_a1_);", - "_od_.push_back(_ad1_);")}; + "_od_.push_back(_ad1_);", + "TODO")}; -#line 4225 "reflect.h2" +#line 4242 "reflect.h2" public: std::string fwd_suffix {"_d"}; public: std::string rws_suffix {"_b"}; private: int order {1}; public: bool reverse {false}; -#line 4231 "reflect.h2" +#line 4248 "reflect.h2" public: std::string fwd_ad_type {"double"}; public: std::string rws_ad_type {"double"}; @@ -1809,91 +1821,91 @@ class autodiff_context { public: explicit autodiff_context(); public: autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_); -#line 4254 "reflect.h2" +#line 4271 "reflect.h2" public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member = false) & -> void; -#line 4258 "reflect.h2" +#line 4275 "reflect.h2" public: [[nodiscard]] auto is_variable_active(cpp2::impl::in name) & -> bool; -#line 4262 "reflect.h2" +#line 4279 "reflect.h2" public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4279 "reflect.h2" +#line 4296 "reflect.h2" public: [[nodiscard]] auto is_forward() const& -> decltype(auto); public: [[nodiscard]] auto is_reverse() const& -> decltype(auto); public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4288 "reflect.h2" +#line 4305 "reflect.h2" public: [[nodiscard]] auto is_type_active(cpp2::impl::in type) & -> bool; -#line 4309 "reflect.h2" +#line 4326 "reflect.h2" public: [[nodiscard]] auto get_fwd_ad_type(cpp2::impl::in type) & -> std::string; -#line 4327 "reflect.h2" +#line 4344 "reflect.h2" public: [[nodiscard]] auto get_rws_ad_type(cpp2::impl::in type) & -> std::string; -#line 4345 "reflect.h2" +#line 4362 "reflect.h2" public: [[nodiscard]] auto get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style; using lookup_declaration_ret = std::vector; -#line 4373 "reflect.h2" +#line 4390 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; -#line 4396 "reflect.h2" +#line 4413 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4413 "reflect.h2" +#line 4430 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; using lookup_member_function_declaration_ret = std::vector; -#line 4423 "reflect.h2" +#line 4440 "reflect.h2" public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4433 "reflect.h2" +#line 4450 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; -struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; }; +struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; std::string code_rws; }; -#line 4443 "reflect.h2" +#line 4460 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4465 "reflect.h2" +#line 4485 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4473 "reflect.h2" +#line 4493 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4493 "reflect.h2" +#line 4513 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4503 "reflect.h2" +#line 4523 "reflect.h2" public: auto enter_function() & -> void; -#line 4508 "reflect.h2" +#line 4528 "reflect.h2" public: auto leave_function() & -> void; -#line 4512 "reflect.h2" +#line 4532 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4525 "reflect.h2" +#line 4545 "reflect.h2" public: auto pop_stack() & -> void; -#line 4540 "reflect.h2" +#line 4560 "reflect.h2" public: auto finish() & -> void; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4545 "reflect.h2" +#line 4565 "reflect.h2" }; class autodiff_diff_code { @@ -1904,59 +1916,59 @@ class autodiff_diff_code { public: std::string rws_backprop {""}; public: autodiff_diff_code(cpp2::impl::in ctx_); -#line 4554 "reflect.h2" +#line 4574 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& ; -#line 4558 "reflect.h2" +#line 4578 "reflect.h2" public: auto add_forward(cpp2::impl::in v) & -> void; public: auto add_reverse_primal(cpp2::impl::in v) & -> void; public: auto add_reverse_backprop(cpp2::impl::in v) & -> void; public: auto reset() & -> void; -#line 4569 "reflect.h2" +#line 4589 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4575 "reflect.h2" +#line 4595 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4580 "reflect.h2" +#line 4600 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4585 "reflect.h2" +#line 4605 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_diff_code const&) -> void = delete; -#line 4588 "reflect.h2" +#line 4608 "reflect.h2" }; -#line 4595 "reflect.h2" +#line 4615 "reflect.h2" class autodiff_activity_check: public simple_traverser { -#line 4598 "reflect.h2" +#line 4618 "reflect.h2" public: autodiff_context* ctx; public: bool active {false}; public: autodiff_activity_check(cpp2::impl::in ctx_); -#line 4605 "reflect.h2" +#line 4625 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4617 "reflect.h2" +#line 4637 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4635 "reflect.h2" +#line 4655 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; -#line 4659 "reflect.h2" +#line 4679 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_activity_check(autodiff_activity_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_activity_check const&) -> void = delete; -#line 4691 "reflect.h2" +#line 4711 "reflect.h2" }; class autodiff_handler_base { @@ -1965,21 +1977,21 @@ class autodiff_handler_base { public: autodiff_diff_code diff; public: autodiff_handler_base(cpp2::impl::in ctx_); -#line 4698 "reflect.h2" +#line 4718 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& ; -#line 4704 "reflect.h2" +#line 4724 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4709 "reflect.h2" +#line 4729 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4715 "reflect.h2" +#line 4735 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -1988,31 +2000,31 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(cpp2::impl::in ctx_); -#line 4725 "reflect.h2" +#line 4745 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; -#line 4734 "reflect.h2" +#line 4754 "reflect.h2" public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; -#line 4743 "reflect.h2" +#line 4763 "reflect.h2" public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4754 "reflect.h2" +#line 4774 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4760 "reflect.h2" +#line 4780 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4772 "reflect.h2" +#line 4792 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4781 "reflect.h2" +#line 4801 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -2022,176 +2034,176 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_rws_name(); -#line 4786 "reflect.h2" +#line 4806 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4797 "reflect.h2" +#line 4817 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4858 "reflect.h2" +#line 4878 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 5007 "reflect.h2" - public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; +#line 5029 "reflect.h2" + public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5042 "reflect.h2" +#line 5074 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5046 "reflect.h2" +#line 5078 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5050 "reflect.h2" +#line 5082 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5054 "reflect.h2" +#line 5086 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5058 "reflect.h2" +#line 5090 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5062 "reflect.h2" +#line 5094 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5066 "reflect.h2" +#line 5098 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5070 "reflect.h2" +#line 5102 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5074 "reflect.h2" +#line 5106 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5078 "reflect.h2" +#line 5110 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5082 "reflect.h2" +#line 5114 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5086 "reflect.h2" +#line 5118 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5117 "reflect.h2" +#line 5149 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5204 "reflect.h2" +#line 5236 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5208 "reflect.h2" +#line 5240 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5224 "reflect.h2" +#line 5256 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5264 "reflect.h2" +#line 5296 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5299 "reflect.h2" +#line 5331 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5305 "reflect.h2" +#line 5337 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5314 "reflect.h2" +#line 5346 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5319 "reflect.h2" +#line 5351 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5324 "reflect.h2" +#line 5356 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5375 "reflect.h2" +#line 5407 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5380 "reflect.h2" +#line 5412 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5385 "reflect.h2" +#line 5417 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5390 "reflect.h2" +#line 5422 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5398 "reflect.h2" +#line 5430 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5415 "reflect.h2" +#line 5447 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5465 "reflect.h2" +#line 5497 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5476 "reflect.h2" +#line 5508 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5480 "reflect.h2" +#line 5512 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5505 "reflect.h2" +#line 5537 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5509 "reflect.h2" +#line 5541 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5513 "reflect.h2" +#line 5545 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5517 "reflect.h2" +#line 5549 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5521 "reflect.h2" +#line 5553 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5525 "reflect.h2" +#line 5557 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5529 "reflect.h2" +#line 5561 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5533 "reflect.h2" +#line 5565 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5537 "reflect.h2" +#line 5569 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5541 "reflect.h2" +#line 5573 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5545 "reflect.h2" +#line 5577 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5549 "reflect.h2" +#line 5581 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5553 "reflect.h2" +#line 5585 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5558 "reflect.h2" +#line 5590 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5590 "reflect.h2" +#line 5622 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5594 "reflect.h2" +#line 5626 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5600 "reflect.h2" +#line 5632 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2201,37 +2213,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5612 "reflect.h2" +#line 5644 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5617 "reflect.h2" +#line 5649 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5775 "reflect.h2" +#line 5807 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5803 "reflect.h2" +#line 5835 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5827 "reflect.h2" +#line 5859 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5832 "reflect.h2" +#line 5864 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5835 "reflect.h2" +#line 5867 "reflect.h2" }; -#line 5838 "reflect.h2" +#line 5870 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5937 "reflect.h2" +#line 5969 "reflect.h2" using error_func = std::function x)>; -#line 5941 "reflect.h2" +#line 5973 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2266,20 +2278,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5949 "reflect.h2" +#line 5981 "reflect.h2" }; -#line 5957 "reflect.h2" +#line 5989 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5965 "reflect.h2" +#line 5997 "reflect.h2" public: explicit regex_token(); -#line 5970 "reflect.h2" +#line 6002 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2291,103 +2303,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 5976 "reflect.h2" +#line 6008 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 5982 "reflect.h2" +#line 6014 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 5988 "reflect.h2" +#line 6020 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 5995 "reflect.h2" +#line 6027 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 5999 "reflect.h2" +#line 6031 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6000 "reflect.h2" +#line 6032 "reflect.h2" }; -#line 6003 "reflect.h2" +#line 6035 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6009 "reflect.h2" +#line 6041 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6016 "reflect.h2" +#line 6048 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6020 "reflect.h2" +#line 6052 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6021 "reflect.h2" +#line 6053 "reflect.h2" }; -#line 6024 "reflect.h2" +#line 6056 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6030 "reflect.h2" +#line 6062 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6034 "reflect.h2" +#line 6066 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6038 "reflect.h2" +#line 6070 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6039 "reflect.h2" +#line 6071 "reflect.h2" }; -#line 6042 "reflect.h2" +#line 6074 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6048 "reflect.h2" +#line 6080 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6055 "reflect.h2" +#line 6087 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6061 "reflect.h2" +#line 6093 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6067 "reflect.h2" +#line 6099 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6075 "reflect.h2" +#line 6107 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2395,10 +2407,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6087 "reflect.h2" +#line 6119 "reflect.h2" }; -#line 6090 "reflect.h2" +#line 6122 "reflect.h2" // // Parse and generation context. // @@ -2414,33 +2426,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6110 "reflect.h2" +#line 6142 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6117 "reflect.h2" +#line 6149 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6129 "reflect.h2" +#line 6161 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6134 "reflect.h2" +#line 6166 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6138 "reflect.h2" +#line 6170 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6152 "reflect.h2" +#line 6184 "reflect.h2" }; -#line 6155 "reflect.h2" +#line 6187 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2453,25 +2465,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6173 "reflect.h2" +#line 6205 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6179 "reflect.h2" +#line 6211 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6186 "reflect.h2" +#line 6218 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6193 "reflect.h2" +#line 6225 "reflect.h2" }; -#line 6196 "reflect.h2" +#line 6228 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2487,7 +2499,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6212 "reflect.h2" +#line 6244 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2495,64 +2507,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6223 "reflect.h2" +#line 6255 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6236 "reflect.h2" +#line 6268 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6244 "reflect.h2" +#line 6276 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6248 "reflect.h2" +#line 6280 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6252 "reflect.h2" +#line 6284 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6264 "reflect.h2" +#line 6296 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6271 "reflect.h2" +#line 6303 "reflect.h2" public: auto next_alternative() & -> void; -#line 6277 "reflect.h2" +#line 6309 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6283 "reflect.h2" +#line 6315 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6287 "reflect.h2" +#line 6319 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6298 "reflect.h2" +#line 6330 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6302 "reflect.h2" +#line 6334 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6308 "reflect.h2" +#line 6340 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6312 "reflect.h2" +#line 6344 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6319 "reflect.h2" +#line 6351 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6330 "reflect.h2" +#line 6362 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2560,51 +2572,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6374 "reflect.h2" +#line 6406 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6386 "reflect.h2" +#line 6418 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6399 "reflect.h2" +#line 6431 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6422 "reflect.h2" +#line 6454 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6439 "reflect.h2" +#line 6471 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6460 "reflect.h2" +#line 6492 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6470 "reflect.h2" +#line 6502 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6474 "reflect.h2" +#line 6506 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6530 "reflect.h2" +#line 6562 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6569 "reflect.h2" +#line 6601 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6584 "reflect.h2" +#line 6616 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2616,10 +2628,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6595 "reflect.h2" +#line 6627 "reflect.h2" }; -#line 6598 "reflect.h2" +#line 6630 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2629,16 +2641,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6612 "reflect.h2" +#line 6644 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6615 "reflect.h2" +#line 6647 "reflect.h2" }; -#line 6618 "reflect.h2" +#line 6650 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2658,68 +2670,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6640 "reflect.h2" +#line 6672 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6646 "reflect.h2" +#line 6678 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6655 "reflect.h2" +#line 6687 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6666 "reflect.h2" +#line 6698 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6673 "reflect.h2" +#line 6705 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6693 "reflect.h2" +#line 6725 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6703 "reflect.h2" +#line 6735 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6726 "reflect.h2" +#line 6758 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6734 "reflect.h2" +#line 6766 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6738 "reflect.h2" +#line 6770 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6744 "reflect.h2" +#line 6776 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6750 "reflect.h2" +#line 6782 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6760 "reflect.h2" +#line 6792 "reflect.h2" public: auto finish_context() & -> void; -#line 6768 "reflect.h2" +#line 6800 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6774 "reflect.h2" +#line 6806 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6778 "reflect.h2" +#line 6810 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6782 "reflect.h2" +#line 6814 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6806 "reflect.h2" +#line 6838 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2727,7 +2739,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6812 "reflect.h2" +#line 6844 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2747,27 +2759,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6831 "reflect.h2" +#line 6863 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6837 "reflect.h2" +#line 6869 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6844 "reflect.h2" +#line 6876 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6861 "reflect.h2" +#line 6893 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6868 "reflect.h2" +#line 6900 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6881 "reflect.h2" +#line 6913 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2775,19 +2787,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6893 "reflect.h2" +#line 6925 "reflect.h2" }; -#line 6896 "reflect.h2" +#line 6928 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6902 "reflect.h2" +#line 6934 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6906 "reflect.h2" +#line 6938 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2795,7 +2807,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6911 "reflect.h2" +#line 6943 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2803,17 +2815,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6919 "reflect.h2" +#line 6951 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6930 "reflect.h2" +#line 6962 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6938 "reflect.h2" +#line 6970 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2821,7 +2833,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6941 "reflect.h2" +#line 6973 "reflect.h2" }; // Regex syntax: a @@ -2829,34 +2841,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6949 "reflect.h2" +#line 6981 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6958 "reflect.h2" +#line 6990 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6964 "reflect.h2" +#line 6996 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 6968 "reflect.h2" +#line 7000 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6991 "reflect.h2" +#line 7023 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7012 "reflect.h2" +#line 7044 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7030 "reflect.h2" +#line 7062 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7045 "reflect.h2" +#line 7077 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7051 "reflect.h2" +#line 7083 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2864,33 +2876,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7055 "reflect.h2" +#line 7087 "reflect.h2" }; -#line 7058 "reflect.h2" +#line 7090 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7064 "reflect.h2" +#line 7096 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7076 "reflect.h2" +#line 7108 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7202 "reflect.h2" +#line 7234 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7211 "reflect.h2" +#line 7243 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7216 "reflect.h2" +#line 7248 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2898,20 +2910,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7223 "reflect.h2" +#line 7255 "reflect.h2" }; -#line 7226 "reflect.h2" +#line 7258 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7267 "reflect.h2" +#line 7299 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7278 "reflect.h2" +#line 7310 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2921,20 +2933,20 @@ class class_token class group_ref_token : public regex_token { -#line 7288 "reflect.h2" +#line 7320 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7300 "reflect.h2" +#line 7332 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7401 "reflect.h2" +#line 7433 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7405 "reflect.h2" +#line 7437 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2942,10 +2954,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7408 "reflect.h2" +#line 7440 "reflect.h2" }; -#line 7411 "reflect.h2" +#line 7443 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2959,29 +2971,29 @@ class group_ref_token class group_token : public regex_token { -#line 7425 "reflect.h2" +#line 7457 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7447 "reflect.h2" +#line 7479 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7461 "reflect.h2" +#line 7493 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7620 "reflect.h2" +#line 7652 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7628 "reflect.h2" +#line 7660 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7646 "reflect.h2" +#line 7678 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7677 "reflect.h2" +#line 7709 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -2990,25 +3002,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7684 "reflect.h2" +#line 7716 "reflect.h2" }; -#line 7687 "reflect.h2" +#line 7719 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7728 "reflect.h2" +#line 7760 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7748 "reflect.h2" +#line 7780 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7764 "reflect.h2" +#line 7796 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3016,20 +3028,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7772 "reflect.h2" +#line 7804 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7781 "reflect.h2" +#line 7813 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7792 "reflect.h2" +#line 7824 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7799 "reflect.h2" +#line 7831 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3037,26 +3049,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7802 "reflect.h2" +#line 7834 "reflect.h2" }; -#line 7805 "reflect.h2" +#line 7837 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7833 "reflect.h2" +#line 7865 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7861 "reflect.h2" +#line 7893 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7867 "reflect.h2" +#line 7899 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3066,22 +3078,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7947 "reflect.h2" +#line 7979 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7959 "reflect.h2" +#line 7991 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 7972 "reflect.h2" +#line 8004 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 7991 "reflect.h2" +#line 8023 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8001 "reflect.h2" +#line 8033 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8012 "reflect.h2" +#line 8044 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3089,16 +3101,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8015 "reflect.h2" +#line 8047 "reflect.h2" }; -#line 8018 "reflect.h2" +#line 8050 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8024 "reflect.h2" +#line 8056 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3107,7 +3119,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8054 "reflect.h2" +#line 8086 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3116,14 +3128,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8076 "reflect.h2" +#line 8108 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8098 "reflect.h2" +#line 8130 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3144,24 +3156,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8121 "reflect.h2" +#line 8153 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8156 "reflect.h2" +#line 8188 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8170 "reflect.h2" +#line 8202 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8182 "reflect.h2" +#line 8214 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8237 "reflect.h2" +#line 8269 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3172,7 +3184,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8369 "reflect.h2" +#line 8401 "reflect.h2" } } @@ -7877,106 +7889,120 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in // autodiff - stub // -#line 4101 "reflect.h2" +#line 4103 "reflect.h2" autodiff_special_func::autodiff_special_func(cpp2::impl::in name_, cpp2::impl::in n_args_, cpp2::impl::in is_member_, cpp2::impl::in code_primal_, cpp2::impl::in code_fwd_, - cpp2::impl::in code_primal_higher_order_, cpp2::impl::in code_fwd_higher_order_) + cpp2::impl::in code_rws_, cpp2::impl::in code_primal_higher_order_, cpp2::impl::in code_fwd_higher_order_, + cpp2::impl::in code_rws_higher_order_) : name{ name_ } , n_args{ n_args_ } , is_member{ is_member_ } , code_primal{ code_primal_ } , code_fwd{ code_fwd_ } + , code_rws{ code_rws_ } , code_primal_higher_order{ code_primal_higher_order_ } - , code_fwd_higher_order{ code_fwd_higher_order_ }{ + , code_fwd_higher_order{ code_fwd_higher_order_ } + , code_rws_higher_order{ code_rws_higher_order_ }{ -#line 4112 "reflect.h2" +#line 4117 "reflect.h2" if (CPP2_UFCS(empty)(code_primal_higher_order)) { code_primal_higher_order = code_primal; } if (CPP2_UFCS(empty)(code_fwd_higher_order)) { code_fwd_higher_order = code_fwd; } + if (CPP2_UFCS(empty)(code_rws_higher_order)) { + code_rws_higher_order = code_rws; + } } -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func const& that) : name{ that.name } , n_args{ that.n_args } , is_member{ that.is_member } , code_primal{ that.code_primal } , code_fwd{ that.code_fwd } + , code_rws{ that.code_rws } , code_primal_higher_order{ that.code_primal_higher_order } - , code_fwd_higher_order{ that.code_fwd_higher_order }{} -#line 4120 "reflect.h2" + , code_fwd_higher_order{ that.code_fwd_higher_order } + , code_rws_higher_order{ that.code_rws_higher_order }{} +#line 4128 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func const& that) -> autodiff_special_func& { name = that.name; n_args = that.n_args; is_member = that.is_member; code_primal = that.code_primal; code_fwd = that.code_fwd; + code_rws = that.code_rws; code_primal_higher_order = that.code_primal_higher_order; code_fwd_higher_order = that.code_fwd_higher_order; + code_rws_higher_order = that.code_rws_higher_order; return *this; } -#line 4120 "reflect.h2" +#line 4128 "reflect.h2" autodiff_special_func::autodiff_special_func(autodiff_special_func&& that) noexcept : name{ std::move(that).name } , n_args{ std::move(that).n_args } , is_member{ std::move(that).is_member } , code_primal{ std::move(that).code_primal } , code_fwd{ std::move(that).code_fwd } + , code_rws{ std::move(that).code_rws } , code_primal_higher_order{ std::move(that).code_primal_higher_order } - , code_fwd_higher_order{ std::move(that).code_fwd_higher_order }{} -#line 4120 "reflect.h2" + , code_fwd_higher_order{ std::move(that).code_fwd_higher_order } + , code_rws_higher_order{ std::move(that).code_rws_higher_order }{} +#line 4128 "reflect.h2" auto autodiff_special_func::operator=(autodiff_special_func&& that) noexcept -> autodiff_special_func& { name = std::move(that).name; n_args = std::move(that).n_args; is_member = std::move(that).is_member; code_primal = std::move(that).code_primal; code_fwd = std::move(that).code_fwd; + code_rws = std::move(that).code_rws; code_primal_higher_order = std::move(that).code_primal_higher_order; code_fwd_higher_order = std::move(that).code_fwd_higher_order; + code_rws_higher_order = std::move(that).code_rws_higher_order; return *this; }// Default copy. -#line 4122 "reflect.h2" +#line 4130 "reflect.h2" [[nodiscard]] auto autodiff_special_func::is_match(cpp2::impl::in o) const& -> bool{ return name == o.name && n_args == o.n_args && is_member == o.is_member; } -#line 4129 "reflect.h2" +#line 4137 "reflect.h2" // TODO: Maybe use variant here. -#line 4133 "reflect.h2" +#line 4141 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(){} -#line 4135 "reflect.h2" +#line 4143 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(cpp2::impl::in name_, cpp2::impl::in decl_, cpp2::impl::in is_active_, cpp2::impl::in is_member_) : name{ name_ } , decl{ decl_ } , is_active{ is_active_ } , is_member{ is_member_ }{ -#line 4140 "reflect.h2" +#line 4148 "reflect.h2" } -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable const& that) : name{ that.name } , decl{ that.decl } , is_active{ that.is_active } , is_member{ that.is_member }{} -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" auto autodiff_declared_variable::operator=(autodiff_declared_variable const& that) -> autodiff_declared_variable& { name = that.name; decl = that.decl; is_active = that.is_active; is_member = that.is_member; return *this; } -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" autodiff_declared_variable::autodiff_declared_variable(autodiff_declared_variable&& that) noexcept : name{ std::move(that).name } , decl{ std::move(that).decl } , is_active{ std::move(that).is_active } , is_member{ std::move(that).is_member }{} -#line 4142 "reflect.h2" +#line 4150 "reflect.h2" auto autodiff_declared_variable::operator=(autodiff_declared_variable&& that) noexcept -> autodiff_declared_variable& { name = std::move(that).name; decl = std::move(that).decl; @@ -7984,21 +8010,21 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in is_member = std::move(that).is_member; return *this; } -#line 4146 "reflect.h2" +#line 4154 "reflect.h2" // namespace + type name -#line 4154 "reflect.h2" +#line 4162 "reflect.h2" autodiff_declaration_stack_item::autodiff_declaration_stack_item(cpp2::impl::in full_name_, cpp2::impl::in decl_) : full_name{ full_name_ } , decl{ decl_ }{ -#line 4157 "reflect.h2" +#line 4165 "reflect.h2" } -#line 4159 "reflect.h2" +#line 4167 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_declaration(cpp2::impl::in decl_name) const& -> lookup_declaration_ret{ std::vector r {}; -#line 4160 "reflect.h2" +#line 4168 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(decl) ) { if (CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, cur); @@ -8008,11 +8034,11 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in }return r; } -#line 4169 "reflect.h2" +#line 4177 "reflect.h2" [[nodiscard]] auto autodiff_declaration_stack_item::lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret{ bool found {false}; autodiff_declared_variable r {}; -#line 4170 "reflect.h2" +#line 4178 "reflect.h2" for ( auto const& cur_context : std::ranges::views::reverse(declared_variables_stack) ) { for ( auto const& cur : cur_context ) { if (cur.name == decl_name) { @@ -8037,7 +8063,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , diff_done{ std::move(that).diff_done } , declared_variables_stack{ std::move(that).declared_variables_stack }{} -#line 4187 "reflect.h2" +#line 4195 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -8048,29 +8074,29 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar /* is_member = */ -#line 4202 "reflect.h2" +#line 4212 "reflect.h2" /* is_member = */ -#line 4208 "reflect.h2" +#line 4220 "reflect.h2" /* is_member = */ -#line 4214 "reflect.h2" +#line 4228 "reflect.h2" /* is_member = */ -#line 4220 "reflect.h2" +#line 4236 "reflect.h2" /* is_member = */ -#line 4230 "reflect.h2" +#line 4247 "reflect.h2" // Members depending on order -#line 4237 "reflect.h2" +#line 4254 "reflect.h2" autodiff_context::autodiff_context(){} -#line 4238 "reflect.h2" +#line 4255 "reflect.h2" autodiff_context::autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_) : order{ order_ } , reverse{ reverse_ }{ -#line 4242 "reflect.h2" +#line 4259 "reflect.h2" if (1 != order) { if (reverse) { fwd_ad_type = "cpp2::taylor"; @@ -8083,17 +8109,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } -#line 4254 "reflect.h2" +#line 4271 "reflect.h2" auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member) & -> void{ CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_active, is_member)); } -#line 4258 "reflect.h2" +#line 4275 "reflect.h2" [[nodiscard]] auto autodiff_context::is_variable_active(cpp2::impl::in name) & -> bool{ return lookup_variable_declaration(name).is_active; } -#line 4262 "reflect.h2" +#line 4279 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -8111,20 +8137,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4279 "reflect.h2" +#line 4296 "reflect.h2" [[nodiscard]] auto autodiff_context::is_forward() const& -> decltype(auto) { return !(reverse) || (reverse && order != 1); } -#line 4280 "reflect.h2" +#line 4297 "reflect.h2" [[nodiscard]] auto autodiff_context::is_reverse() const& -> decltype(auto) { return reverse; } -#line 4281 "reflect.h2" +#line 4298 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4283 "reflect.h2" +#line 4300 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4288 "reflect.h2" +#line 4305 "reflect.h2" [[nodiscard]] auto autodiff_context::is_type_active(cpp2::impl::in type) & -> bool{ auto decls {lookup_type_declaration(type)}; auto r {false}; @@ -8146,7 +8172,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4309 "reflect.h2" +#line 4326 "reflect.h2" [[nodiscard]] auto autodiff_context::get_fwd_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8165,7 +8191,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", fwd_ad_type); } -#line 4327 "reflect.h2" +#line 4344 "reflect.h2" [[nodiscard]] auto autodiff_context::get_rws_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8184,7 +8210,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", rws_ad_type); } -#line 4345 "reflect.h2" +#line 4362 "reflect.h2" [[nodiscard]] auto autodiff_context::get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style{ // TODO: inspect does not work here: error: error: no matching function for call to ‘is(const cpp2::passing_style&)’ // return inspect p -> passing_style { @@ -8207,16 +8233,16 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar if (p == passing_style::forward) { return passing_style::inout; } if (p == passing_style::forward_ref) { return passing_style::inout; } -#line 4368 "reflect.h2" +#line 4385 "reflect.h2" CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Do not know how to handle passing style:" + cpp2::to_string(p) + ""); return passing_style::inout; } -#line 4373 "reflect.h2" +#line 4390 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4374 "reflect.h2" +#line 4391 "reflect.h2" for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { std::string cur_full_name {cur.full_name + "::" + decl_name}; @@ -8239,7 +8265,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4396 "reflect.h2" +#line 4413 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ if (name == "_") { return autodiff_declared_variable(name, "_", false, false); @@ -8257,10 +8283,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return autodiff_declared_variable(); } -#line 4413 "reflect.h2" +#line 4430 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4414 "reflect.h2" +#line 4431 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8270,10 +8296,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4423 "reflect.h2" +#line 4440 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ std::vector r {}; -#line 4424 "reflect.h2" +#line 4441 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); @@ -8283,10 +8309,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4433 "reflect.h2" +#line 4450 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4434 "reflect.h2" +#line 4451 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8296,34 +8322,38 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4443 "reflect.h2" +#line 4460 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; -#line 4444 "reflect.h2" + cpp2::impl::deferred_init code_rws; +#line 4461 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); code_primal.construct(""); code_fwd.construct(""); + code_rws.construct(""); for ( auto const& func : special_funcs ) { if (CPP2_UFCS(is_match)(func, lookup)) { m.value() = true; if (is_taylor()) { code_primal.value() = func.code_primal_higher_order; code_fwd.value() = func.code_fwd_higher_order; + code_rws.value() = func.code_rws_higher_order; } else { code_primal.value() = func.code_primal; code_fwd.value() = func.code_fwd; + code_rws.value() = func.code_rws; } - return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; + return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()), std::move(code_rws.value()) }; } - }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()) }; + }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()), std::move(code_rws.value()) }; } -#line 4465 "reflect.h2" +#line 4485 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -8332,7 +8362,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4473 "reflect.h2" +#line 4493 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; @@ -8353,7 +8383,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4493 "reflect.h2" +#line 4513 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -8364,18 +8394,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4503 "reflect.h2" +#line 4523 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4508 "reflect.h2" +#line 4528 "reflect.h2" auto autodiff_context::leave_function() & -> void{ CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4512 "reflect.h2" +#line 4532 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -8389,7 +8419,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4525 "reflect.h2" +#line 4545 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -8405,20 +8435,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4540 "reflect.h2" +#line 4560 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4554 "reflect.h2" +#line 4574 "reflect.h2" autodiff_diff_code::autodiff_diff_code(cpp2::impl::in ctx_) : ctx{ ctx_ }{ -#line 4556 "reflect.h2" +#line 4576 "reflect.h2" } -#line 4554 "reflect.h2" +#line 4574 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& { ctx = ctx_; fwd = ""; @@ -8426,17 +8456,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4556 "reflect.h2" +#line 4576 "reflect.h2" } -#line 4558 "reflect.h2" +#line 4578 "reflect.h2" auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} -#line 4559 "reflect.h2" +#line 4579 "reflect.h2" auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} -#line 4560 "reflect.h2" +#line 4580 "reflect.h2" auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop = v + rws_backprop; }} -#line 4562 "reflect.h2" +#line 4582 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ fwd = ""; rws_primal = ""; @@ -8444,7 +8474,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4569 "reflect.h2" +#line 4589 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; @@ -8452,42 +8482,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4572 "reflect.h2" +#line 4592 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4575 "reflect.h2" +#line 4595 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4580 "reflect.h2" +#line 4600 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4585 "reflect.h2" +#line 4605 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4590 "reflect.h2" +#line 4610 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4601 "reflect.h2" +#line 4621 "reflect.h2" autodiff_activity_check::autodiff_activity_check(cpp2::impl::in ctx_) : simple_traverser{ } , ctx{ ctx_ }{ -#line 4603 "reflect.h2" +#line 4623 "reflect.h2" } -#line 4605 "reflect.h2" +#line 4625 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in t) -> void{ for ( auto const& m : CPP2_UFCS(get_members)(t) ) @@ -8500,7 +8530,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4617 "reflect.h2" +#line 4637 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in o) -> void{ auto type {o.type()}; @@ -8519,7 +8549,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4635 "reflect.h2" +#line 4655 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8544,7 +8574,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }}}} } -#line 4659 "reflect.h2" +#line 4679 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8553,7 +8583,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4666 "reflect.h2" +#line 4686 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8569,7 +8599,7 @@ auto i{0}; } // TODO: Really check for members -#line 4680 "reflect.h2" +#line 4700 "reflect.h2" if (!(is_func) || CPP2_UFCS(ssize)(terms) != 1) { active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))); } @@ -8582,39 +8612,39 @@ auto i{0}; } } -#line 4698 "reflect.h2" +#line 4718 "reflect.h2" autodiff_handler_base::autodiff_handler_base(cpp2::impl::in ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4701 "reflect.h2" +#line 4721 "reflect.h2" } -#line 4698 "reflect.h2" +#line 4718 "reflect.h2" auto autodiff_handler_base::operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4701 "reflect.h2" +#line 4721 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4704 "reflect.h2" +#line 4724 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff.fwd += o.diff.fwd; diff.rws_primal += o.diff.rws_primal; diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4721 "reflect.h2" +#line 4741 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(cpp2::impl::in ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4723 "reflect.h2" +#line 4743 "reflect.h2" } -#line 4725 "reflect.h2" +#line 4745 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8624,7 +8654,7 @@ auto i{0}; } } -#line 4734 "reflect.h2" +#line 4754 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ auto r {rhs_b}; r = string_util::replace_all(r, "_r_", lhs); @@ -8634,7 +8664,7 @@ auto i{0}; return r; } -#line 4743 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8646,14 +8676,14 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4754 "reflect.h2" +#line 4774 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4756 "reflect.h2" +#line 4776 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4760 "reflect.h2" +#line 4780 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8666,13 +8696,13 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4772 "reflect.h2" +#line 4792 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4774 "reflect.h2" +#line 4794 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4776 "reflect.h2" +#line 4796 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } @@ -8684,7 +8714,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8694,7 +8724,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4797 "reflect.h2" +#line 4817 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8756,7 +8786,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} }} } -#line 4858 "reflect.h2" +#line 4878 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8764,7 +8794,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4864 "reflect.h2" +#line 4884 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8778,7 +8808,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4876 "reflect.h2" +#line 4896 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8786,6 +8816,7 @@ auto i{0}; std::string object {""}; std::string object_d {""}; + std::string object_b {""}; std::string function_name {""}; std::vector args {}; @@ -8793,7 +8824,8 @@ auto i{0}; if (1 != CPP2_UFCS(ssize)(terms)) { object = CPP2_UFCS(to_string)(primary); - object_d = CPP2_UFCS(to_string)(cpp2::move(primary)) + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; + object_d = CPP2_UFCS(to_string)(primary) + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix; + object_b = CPP2_UFCS(to_string)(cpp2::move(primary)) + (*cpp2::impl::assert_not_null(ctx)).rws_suffix; } else { function_name = CPP2_UFCS(to_string)(cpp2::move(primary)); @@ -8801,7 +8833,7 @@ auto i{0}; { auto i{0}; -#line 4897 "reflect.h2" +#line 4919 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8826,8 +8858,8 @@ auto i{0}; } while (false); i += 1; } } -#line 4920 "reflect.h2" - if (handle_special_function(object, object_d, function_name, args)) { +#line 4942 "reflect.h2" + if (handle_special_function(object, object_d, cpp2::move(object_b), function_name, args)) { return ; } @@ -8914,8 +8946,8 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 5007 "reflect.h2" - [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ +#line 5029 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8925,7 +8957,8 @@ auto i{0}; // Have a match, do the replacement std::string code_primal {r.code_primal}; - std::string code_fwd {cpp2::move(r).code_fwd}; + std::string code_fwd {r.code_fwd}; + std::string code_rws {cpp2::move(r).code_rws}; if (!(CPP2_UFCS(empty)(object))) { code_primal = string_util::replace_all(code_primal, "_o_", object); @@ -8933,83 +8966,92 @@ auto i{0}; code_fwd = string_util::replace_all(code_fwd, "_o_", object); code_fwd = string_util::replace_all(code_fwd, "_od_", object_d); + + code_rws = string_util::replace_all(code_fwd, "_o_", object); + code_rws = string_util::replace_all(code_rws, "_od_", object_d); + code_rws = string_util::replace_all(code_fwd, "_ob_", object_b); } { auto i{1}; -#line 5028 "reflect.h2" +#line 5055 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); code_fwd = string_util::replace_all(code_fwd, "_a" + cpp2::to_string(i) + "_", arg.primal); code_fwd = string_util::replace_all(code_fwd, "_ad" + cpp2::to_string(i) + "_", arg.fwd); + + code_rws = string_util::replace_all(code_rws, "_a" + cpp2::to_string(i) + "_", arg.primal); + code_rws = string_util::replace_all(code_rws, "_ad" + cpp2::to_string(i) + "_", arg.fwd); + code_rws = string_util::replace_all(code_rws, "_ab" + cpp2::to_string(i) + "_", arg.rws); } } -#line 5036 "reflect.h2" +#line 5067 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); + rws_expr = cpp2::move(code_rws); return true; } -#line 5042 "reflect.h2" +#line 5074 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5046 "reflect.h2" +#line 5078 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5050 "reflect.h2" +#line 5082 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5054 "reflect.h2" +#line 5086 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5058 "reflect.h2" +#line 5090 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5062 "reflect.h2" +#line 5094 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5066 "reflect.h2" +#line 5098 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5070 "reflect.h2" +#line 5102 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5074 "reflect.h2" +#line 5106 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5078 "reflect.h2" +#line 5110 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5082 "reflect.h2" +#line 5114 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5086 "reflect.h2" +#line 5118 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9041,7 +9083,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5117 "reflect.h2" +#line 5149 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9112,7 +9154,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5188 "reflect.h2" +#line 5220 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9129,12 +9171,12 @@ auto i{1}; } } -#line 5204 "reflect.h2" +#line 5236 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5208 "reflect.h2" +#line 5240 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9151,7 +9193,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5224 "reflect.h2" +#line 5256 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9160,7 +9202,7 @@ auto i{1}; { auto i{0}; -#line 5231 "reflect.h2" +#line 5263 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9175,7 +9217,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5244 "reflect.h2" +#line 5276 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9196,7 +9238,7 @@ auto i{0}; } } -#line 5264 "reflect.h2" +#line 5296 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9233,26 +9275,26 @@ auto i{0}; }}}} } -#line 5309 "reflect.h2" +#line 5341 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5312 "reflect.h2" +#line 5344 "reflect.h2" } -#line 5314 "reflect.h2" +#line 5346 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5319 "reflect.h2" +#line 5351 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5324 "reflect.h2" +#line 5356 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9303,22 +9345,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5375 "reflect.h2" +#line 5407 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5380 "reflect.h2" +#line 5412 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5385 "reflect.h2" +#line 5417 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5390 "reflect.h2" +#line 5422 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -9326,7 +9368,7 @@ auto i{0}; diff += "}\n"; } -#line 5398 "reflect.h2" +#line 5430 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9343,7 +9385,7 @@ auto i{0}; } } -#line 5415 "reflect.h2" +#line 5447 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -9393,7 +9435,7 @@ auto i{0}; }} } -#line 5465 "reflect.h2" +#line 5497 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9405,12 +9447,12 @@ auto i{0}; } } -#line 5476 "reflect.h2" +#line 5508 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5480 "reflect.h2" +#line 5512 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9436,73 +9478,73 @@ auto i{0}; } } -#line 5505 "reflect.h2" +#line 5537 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5509 "reflect.h2" +#line 5541 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5513 "reflect.h2" +#line 5545 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5517 "reflect.h2" +#line 5549 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5521 "reflect.h2" +#line 5553 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5525 "reflect.h2" +#line 5557 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5529 "reflect.h2" +#line 5561 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5533 "reflect.h2" +#line 5565 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5537 "reflect.h2" +#line 5569 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5541 "reflect.h2" +#line 5573 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5545 "reflect.h2" +#line 5577 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5549 "reflect.h2" +#line 5581 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5553 "reflect.h2" +#line 5585 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5558 "reflect.h2" +#line 5590 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9511,7 +9553,7 @@ auto i{0}; { auto i{0}; -#line 5565 "reflect.h2" +#line 5597 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9526,7 +9568,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5578 "reflect.h2" +#line 5610 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9539,27 +9581,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5590 "reflect.h2" +#line 5622 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5607 "reflect.h2" +#line 5639 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5610 "reflect.h2" +#line 5642 "reflect.h2" } -#line 5612 "reflect.h2" +#line 5644 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5617 "reflect.h2" +#line 5649 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9689,10 +9731,10 @@ auto i{0}; return ; } -#line 5747 "reflect.h2" +#line 5779 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5750 "reflect.h2" +#line 5782 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9717,7 +9759,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5775 "reflect.h2" +#line 5807 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9745,7 +9787,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5803 "reflect.h2" +#line 5835 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9769,17 +9811,17 @@ auto i{0}; } } -#line 5827 "reflect.h2" +#line 5859 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5832 "reflect.h2" +#line 5864 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5838 "reflect.h2" +#line 5870 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9955,7 +9997,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5923 "reflect.h2" +#line 5955 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -9971,11 +10013,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5939 "reflect.h2" +#line 5971 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5943 "reflect.h2" +#line 5975 "reflect.h2" // mod: i // mod: m // mod: s @@ -9983,116 +10025,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5952 "reflect.h2" +#line 5984 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5961 "reflect.h2" +#line 5993 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5963 "reflect.h2" +#line 5995 "reflect.h2" } -#line 5965 "reflect.h2" +#line 5997 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5967 "reflect.h2" +#line 5999 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 5973 "reflect.h2" +#line 6005 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 5974 "reflect.h2" +#line 6006 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 5975 "reflect.h2" +#line 6007 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 5990 "reflect.h2" +#line 6022 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 5993 "reflect.h2" +#line 6025 "reflect.h2" } -#line 5995 "reflect.h2" +#line 6027 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 5999 "reflect.h2" +#line 6031 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6011 "reflect.h2" +#line 6043 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6014 "reflect.h2" +#line 6046 "reflect.h2" } -#line 6016 "reflect.h2" +#line 6048 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6020 "reflect.h2" +#line 6052 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6030 "reflect.h2" +#line 6062 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6032 "reflect.h2" +#line 6064 "reflect.h2" } -#line 6034 "reflect.h2" +#line 6066 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6038 "reflect.h2" +#line 6070 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6050 "reflect.h2" +#line 6082 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6053 "reflect.h2" +#line 6085 "reflect.h2" } -#line 6055 "reflect.h2" +#line 6087 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6061 "reflect.h2" +#line 6093 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6067 "reflect.h2" +#line 6099 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10101,7 +10143,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6075 "reflect.h2" +#line 6107 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10117,7 +10159,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6103 "reflect.h2" +#line 6135 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10125,14 +10167,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6111 "reflect.h2" +#line 6143 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6118 "reflect.h2" +#line 6150 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10144,15 +10186,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6130 "reflect.h2" +#line 6162 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6135 "reflect.h2" +#line 6167 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6139 "reflect.h2" +#line 6171 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10173,7 +10215,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6165 "reflect.h2" +#line 6197 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10182,20 +10224,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6174 "reflect.h2" +#line 6206 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6180 "reflect.h2" +#line 6212 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6187 "reflect.h2" +#line 6219 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10210,16 +10252,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6217 "reflect.h2" +#line 6249 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6221 "reflect.h2" +#line 6253 "reflect.h2" } -#line 6227 "reflect.h2" +#line 6259 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10229,7 +10271,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6237 "reflect.h2" +#line 6269 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10237,17 +10279,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6244 "reflect.h2" +#line 6276 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6248 "reflect.h2" +#line 6280 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6255 "reflect.h2" +#line 6287 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10257,7 +10299,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6264 "reflect.h2" +#line 6296 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10265,24 +10307,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6271 "reflect.h2" +#line 6303 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6279 "reflect.h2" +#line 6311 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6283 "reflect.h2" +#line 6315 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6287 "reflect.h2" +#line 6319 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10294,22 +10336,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6298 "reflect.h2" +#line 6330 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6304 "reflect.h2" +#line 6336 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6308 "reflect.h2" +#line 6340 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6312 "reflect.h2" +#line 6344 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10317,7 +10359,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6319 "reflect.h2" +#line 6351 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10329,10 +10371,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6332 "reflect.h2" +#line 6364 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6335 "reflect.h2" +#line 6367 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10372,7 +10414,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6375 "reflect.h2" +#line 6407 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10384,14 +10426,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6386 "reflect.h2" +#line 6418 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6387 "reflect.h2" +#line 6419 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6388 "reflect.h2" +#line 6420 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6390 "reflect.h2" +#line 6422 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10401,10 +10443,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6399 "reflect.h2" +#line 6431 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6401 "reflect.h2" +#line 6433 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10426,14 +10468,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6422 "reflect.h2" +#line 6454 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6423 "reflect.h2" +#line 6455 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6424 "reflect.h2" +#line 6456 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6426 "reflect.h2" +#line 6458 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10447,7 +10489,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6439 "reflect.h2" +#line 6471 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10469,7 +10511,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6460 "reflect.h2" +#line 6492 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10480,12 +10522,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6470 "reflect.h2" +#line 6502 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6471 "reflect.h2" +#line 6503 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6476 "reflect.h2" +#line 6508 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10540,7 +10582,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6530 "reflect.h2" +#line 6562 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10580,7 +10622,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6569 "reflect.h2" +#line 6601 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10596,21 +10638,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6586 "reflect.h2" +#line 6618 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6587 "reflect.h2" +#line 6619 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6588 "reflect.h2" +#line 6620 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6590 "reflect.h2" +#line 6622 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6605 "reflect.h2" +#line 6637 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10618,7 +10660,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6612 "reflect.h2" +#line 6644 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10628,22 +10670,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6630 "reflect.h2" +#line 6662 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6635 "reflect.h2" +#line 6667 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6641 "reflect.h2" +#line 6673 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6647 "reflect.h2" +#line 6679 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10652,7 +10694,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6655 "reflect.h2" +#line 6687 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10664,7 +10706,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6666 "reflect.h2" +#line 6698 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10672,7 +10714,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6673 "reflect.h2" +#line 6705 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10693,7 +10735,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6694 "reflect.h2" +#line 6726 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10703,7 +10745,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6704 "reflect.h2" +#line 6736 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10726,33 +10768,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6728 "reflect.h2" +#line 6760 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6734 "reflect.h2" +#line 6766 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6738 "reflect.h2" +#line 6770 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6744 "reflect.h2" +#line 6776 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6752 "reflect.h2" +#line 6784 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10761,7 +10803,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6760 "reflect.h2" +#line 6792 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10770,22 +10812,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6770 "reflect.h2" +#line 6802 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6774 "reflect.h2" +#line 6806 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6778 "reflect.h2" +#line 6810 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6782 "reflect.h2" +#line 6814 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10809,18 +10851,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6807 "reflect.h2" +#line 6839 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6822 "reflect.h2" +#line 6854 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6824 "reflect.h2" +#line 6856 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10831,15 +10873,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6839 "reflect.h2" +#line 6871 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6842 "reflect.h2" +#line 6874 "reflect.h2" } -#line 6844 "reflect.h2" +#line 6876 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10857,7 +10899,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6861 "reflect.h2" +#line 6893 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10865,7 +10907,7 @@ generation_function_context::generation_function_context(){} } } -#line 6868 "reflect.h2" +#line 6900 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10879,7 +10921,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6881 "reflect.h2" +#line 6913 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10895,14 +10937,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6902 "reflect.h2" +#line 6934 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6904 "reflect.h2" +#line 6936 "reflect.h2" } -#line 6906 "reflect.h2" +#line 6938 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10911,11 +10953,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6921 "reflect.h2" +#line 6953 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6923 "reflect.h2" +#line 6955 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10923,7 +10965,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6930 "reflect.h2" +#line 6962 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10932,37 +10974,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6938 "reflect.h2" +#line 6970 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6952 "reflect.h2" +#line 6984 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6956 "reflect.h2" +#line 6988 "reflect.h2" } -#line 6958 "reflect.h2" +#line 6990 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6962 "reflect.h2" +#line 6994 "reflect.h2" } -#line 6964 "reflect.h2" +#line 6996 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 6968 "reflect.h2" +#line 7000 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -10971,14 +11013,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 6974 "reflect.h2" +#line 7006 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 6979 "reflect.h2" +#line 7011 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -10991,7 +11033,7 @@ size_t i{0}; } } -#line 6991 "reflect.h2" +#line 7023 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11013,7 +11055,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7012 "reflect.h2" +#line 7044 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11032,7 +11074,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7030 "reflect.h2" +#line 7062 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11048,14 +11090,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7045 "reflect.h2" +#line 7077 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7051 "reflect.h2" +#line 7083 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11063,19 +11105,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7068 "reflect.h2" +#line 7100 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7069 "reflect.h2" +#line 7101 "reflect.h2" { -#line 7074 "reflect.h2" +#line 7106 "reflect.h2" } -#line 7077 "reflect.h2" +#line 7109 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11201,7 +11243,7 @@ size_t i{0}; ); } -#line 7202 "reflect.h2" +#line 7234 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11211,13 +11253,13 @@ size_t i{0}; ); } -#line 7211 "reflect.h2" +#line 7243 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7216 "reflect.h2" +#line 7248 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11228,12 +11270,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7228 "reflect.h2" +#line 7260 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7233 "reflect.h2" +#line 7265 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11267,7 +11309,7 @@ size_t i{0}; } -#line 7269 "reflect.h2" +#line 7301 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11276,19 +11318,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7292 "reflect.h2" +#line 7324 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7293 "reflect.h2" +#line 7325 "reflect.h2" { -#line 7298 "reflect.h2" +#line 7330 "reflect.h2" } -#line 7300 "reflect.h2" +#line 7332 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11390,19 +11432,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7401 "reflect.h2" +#line 7433 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7405 "reflect.h2" +#line 7437 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7429 "reflect.h2" +#line 7461 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11421,7 +11463,7 @@ size_t i{0}; return r; } -#line 7447 "reflect.h2" +#line 7479 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11436,7 +11478,7 @@ size_t i{0}; return r; } -#line 7461 "reflect.h2" +#line 7493 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11596,7 +11638,7 @@ size_t i{0}; } } -#line 7620 "reflect.h2" +#line 7652 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11605,7 +11647,7 @@ size_t i{0}; return r; } -#line 7628 "reflect.h2" +#line 7660 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11624,7 +11666,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7646 "reflect.h2" +#line 7678 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11656,7 +11698,7 @@ size_t i{0}; } } -#line 7677 "reflect.h2" +#line 7709 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11667,7 +11709,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7689 "reflect.h2" +#line 7721 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11706,7 +11748,7 @@ size_t i{0}; return r; } -#line 7730 "reflect.h2" +#line 7762 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11724,7 +11766,7 @@ size_t i{0}; }} } -#line 7750 "reflect.h2" +#line 7782 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11738,16 +11780,16 @@ size_t i{0}; } } -#line 7776 "reflect.h2" +#line 7808 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7779 "reflect.h2" +#line 7811 "reflect.h2" } -#line 7781 "reflect.h2" +#line 7813 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11759,7 +11801,7 @@ size_t i{0}; } } -#line 7792 "reflect.h2" +#line 7824 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11767,14 +11809,14 @@ size_t i{0}; return r; } -#line 7799 "reflect.h2" +#line 7831 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7807 "reflect.h2" +#line 7839 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11800,7 +11842,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7835 "reflect.h2" +#line 7867 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11826,11 +11868,11 @@ size_t i{0}; return r; } -#line 7872 "reflect.h2" +#line 7904 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7874 "reflect.h2" +#line 7906 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11904,7 +11946,7 @@ size_t i{0}; return nullptr; } -#line 7947 "reflect.h2" +#line 7979 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11917,7 +11959,7 @@ size_t i{0}; }} } -#line 7959 "reflect.h2" +#line 7991 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11931,7 +11973,7 @@ size_t i{0}; }} } -#line 7972 "reflect.h2" +#line 8004 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11951,7 +11993,7 @@ size_t i{0}; return r; } -#line 7991 "reflect.h2" +#line 8023 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -11962,7 +12004,7 @@ size_t i{0}; return r; } -#line 8001 "reflect.h2" +#line 8033 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11974,14 +12016,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8012 "reflect.h2" +#line 8044 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8024 "reflect.h2" +#line 8056 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12005,7 +12047,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8048 "reflect.h2" +#line 8080 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12015,7 +12057,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8060 "reflect.h2" +#line 8092 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12031,7 +12073,7 @@ size_t i{0}; } } -#line 8080 "reflect.h2" +#line 8112 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12049,15 +12091,15 @@ size_t i{0}; }} } -#line 8116 "reflect.h2" +#line 8148 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8119 "reflect.h2" +#line 8151 "reflect.h2" } -#line 8121 "reflect.h2" +#line 8153 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12093,7 +12135,7 @@ size_t i{0}; return source; } -#line 8156 "reflect.h2" +#line 8188 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12109,7 +12151,7 @@ size_t i{0}; } } -#line 8172 "reflect.h2" +#line 8204 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12118,7 +12160,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12173,7 +12215,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8241 "reflect.h2" +#line 8273 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12301,7 +12343,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8369 "reflect.h2" +#line 8401 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index a0dec8f6a..848c46b6e 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4095,19 +4095,24 @@ autodiff_special_func: type = { public code_primal : std::string; public code_fwd : std::string; + public code_rws : std::string; public code_primal_higher_order: std::string; public code_fwd_higher_order : std::string; + public code_rws_higher_order : std::string; operator=: (out this, name_: std::string, n_args_: int, is_member_: bool, code_primal_: std::string = "", code_fwd_: std::string = "", - code_primal_higher_order_: std::string = "", code_fwd_higher_order_: std::string = "") = { + code_rws_: std::string = "", code_primal_higher_order_: std::string = "", code_fwd_higher_order_: std::string = "", + code_rws_higher_order_: std::string = "") = { name = name_; n_args = n_args_; is_member = is_member_; code_primal = code_primal_; code_fwd = code_fwd_; + code_rws = code_rws_; code_primal_higher_order = code_primal_higher_order_; code_fwd_higher_order = code_fwd_higher_order_; + code_rws_higher_order = code_rws_higher_order_; if code_primal_higher_order.empty() { code_primal_higher_order = code_primal; @@ -4115,6 +4120,9 @@ autodiff_special_func: type = { if code_fwd_higher_order.empty() { code_fwd_higher_order = code_fwd; } + if code_rws_higher_order.empty() { + code_rws_higher_order = code_rws; + } } operator=: (out this, that) = {} // Default copy. @@ -4195,31 +4203,40 @@ autodiff_context: type = { autodiff_special_func("sin", 1, /* is_member = */ false, "sin(_a1_)", "cos(_a1_) * _ad1_", + "_ab1_ += cos(_a1_) * _rb_;\n", "sin(_a1_)", "_ad1_.sin(_a1_)", + "TODO", ), autodiff_special_func("cos", 1, /* is_member = */ false, "cos(_a1_)", "-sin(_a1_) * _ad1_", + "_ab1_ += -sin(_a1_) * _rb_;\n", "cos(_a1_)", "_ad1_.cos(_a1_)", + "TODO", ), autodiff_special_func("exp", 1, /* is_member = */ false, "exp(_a1_)", "exp(_a1_) * _ad1_", + "_ab1_ += exp(_a1_) * _rb_;\n", "exp(_a1_)", "_ad1_.exp(_a1_)", + "TODO", ), autodiff_special_func("sqrt", 1, /* is_member = */ false, "sqrt(_a1_)", "0.5 * _ad1_ / sqrt(_a1_)", + "_ab1_ += 0.5 * _rb_ / sqrt(_a1_);\n", "sqrt(_a1_)", "_ad1_.sqrt(_a1_)", + "TODO", ), autodiff_special_func("push_back", 1, /* is_member = */ true, "_o_.push_back(_a1_);", - "_od_.push_back(_ad1_);") + "_od_.push_back(_ad1_);", + "TODO") ); public fwd_suffix : std::string = "_d"; @@ -4440,22 +4457,25 @@ autodiff_context: type = { } } - lookup_special_function_handling: (this, func_name: std::string, n_args: int, is_member: bool) -> (m: bool, code_primal: std::string, code_fwd: std::string) = { + lookup_special_function_handling: (this, func_name: std::string, n_args: int, is_member: bool) -> (m: bool, code_primal: std::string, code_fwd: std::string, code_rws: std::string) = { lookup : autodiff_special_func = (func_name, n_args, is_member); m = false; code_primal = ""; code_fwd = ""; + code_rws = ""; for special_funcs do (func) { if func.is_match(lookup) { m = true; if is_taylor() { code_primal = func.code_primal_higher_order; code_fwd = func.code_fwd_higher_order; + code_rws = func.code_rws_higher_order; } else { code_primal = func.code_primal; code_fwd = func.code_fwd; + code_rws = func.code_rws; } return; } @@ -4880,6 +4900,7 @@ autodiff_expression_handler: type = { object : std::string = ""; object_d : std::string = ""; + object_b : std::string = ""; function_name : std::string = ""; args : std::vector = (); @@ -4888,6 +4909,7 @@ autodiff_expression_handler: type = { if 1 != terms.ssize() { object = primary.to_string(); object_d = primary.to_string() + ctx*.fwd_suffix; + object_b = primary.to_string() + ctx*.rws_suffix; } else { function_name = primary.to_string(); @@ -4917,7 +4939,7 @@ autodiff_expression_handler: type = { } } - if handle_special_function(object, object_d, function_name, args) { + if handle_special_function(object, object_d, object_b, function_name, args) { return; } @@ -5004,7 +5026,7 @@ autodiff_expression_handler: type = { // TODO: Add function to list of functions/objects for differentiation for the no return case. } - handle_special_function: (inout this, object: std::string, object_d: std::string, function_name: std::string, args: std::vector) -> bool = { + handle_special_function: (inout this, object: std::string, object_d: std::string, object_b: std::string, function_name: std::string, args: std::vector) -> bool = { r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !object.empty()); @@ -5015,6 +5037,7 @@ autodiff_expression_handler: type = { // Have a match, do the replacement code_primal: std::string = r.code_primal; code_fwd : std::string = r.code_fwd; + code_rws : std::string = r.code_rws; if !object.empty() { code_primal = string_util::replace_all(code_primal, "_o_", object); @@ -5022,6 +5045,10 @@ autodiff_expression_handler: type = { code_fwd = string_util::replace_all(code_fwd, "_o_", object); code_fwd = string_util::replace_all(code_fwd, "_od_", object_d); + + code_rws = string_util::replace_all(code_fwd, "_o_", object); + code_rws = string_util::replace_all(code_rws, "_od_", object_d); + code_rws = string_util::replace_all(code_fwd, "_ob_", object_b); } (copy i := 1) @@ -5031,10 +5058,15 @@ autodiff_expression_handler: type = { code_fwd = string_util::replace_all(code_fwd, "_a(i)$_", arg.primal); code_fwd = string_util::replace_all(code_fwd, "_ad(i)$_", arg.fwd); + + code_rws = string_util::replace_all(code_rws, "_a(i)$_", arg.primal); + code_rws = string_util::replace_all(code_rws, "_ad(i)$_", arg.fwd); + code_rws = string_util::replace_all(code_rws, "_ab(i)$_", arg.rws); } primal_expr = code_primal; fwd_expr = code_fwd; + rws_expr = code_rws; return true; } From 75046838f73574ea5434cf89001feb149b6a6b83 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 29 Aug 2025 11:53:12 +0200 Subject: [PATCH 48/54] Added handling of function calls for reverse. --- regression-tests/pure2-autodiff.cpp2 | 14 + .../gcc-13-c++2b/pure2-autodiff.cpp.execution | 2 + .../test-results/pure2-autodiff.cpp | 132 +- .../test-results/pure2-autodiff.cpp2.output | 86 +- source/reflect.h | 1061 +++++++++-------- source/reflect.h2 | 49 +- 6 files changed, 795 insertions(+), 549 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 2e94dfcae..f1d789627 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -244,6 +244,18 @@ ad_test_reverse: @autodiff<"reverse"> @print type = { sin_call: (x: double, y: double) -> (r: double) = { r = sin(x - y); } + + func: (x: double, y: double) -> (ret: double) = { + ret = x + y; + } + + func_call: (x: double, y: double) -> (r: double) = { + r = x * func(x, y); + } + + func_outer_call: (x: double, y: double) -> (r: double) = { + r = x * func_outer(x, y); + } } } @@ -319,6 +331,8 @@ main: () = { write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, y, y_b, w_b)); write_output_reverse("sin(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sin_call_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * func(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::func_call_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * func_outer(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::func_outer_call_b(x, x_b, y, y_b, w_b)); _ = x_b; _ = y_b; diff --git a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution index e243e4449..863bd6bd5 100644 --- a/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution +++ b/regression-tests/test-results/gcc-13-c++2b/pure2-autodiff.cpp.execution @@ -41,4 +41,6 @@ diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) +diff(x * func(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x * func_outer(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) 2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index c4a639711..67cfe16eb 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -21,7 +21,7 @@ class ad_test; #line 194 "pure2-autodiff.cpp2" class ad_test_reverse; -#line 248 "pure2-autodiff.cpp2" +#line 260 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -355,6 +355,11 @@ public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cp #line 192 "pure2-autodiff.cpp2" }; +using func_outer_b_ret = double; + +[[nodiscard]] auto func_outer_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& ret_b) -> func_outer_b_ret; + +#line 194 "pure2-autodiff.cpp2" class ad_test_reverse { using add_1_ret = double; @@ -421,6 +426,21 @@ using sin_call_ret = double; #line 244 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; +using func_ret = double; + + +#line 248 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; +using func_call_ret = double; + + +#line 252 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; +using func_outer_call_ret = double; + + +#line 256 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using add_1_b_ret = double; public: [[nodiscard]] static auto add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret; @@ -461,19 +481,28 @@ public: [[nodiscard]] static auto add_mul_b(cpp2::impl::in x, double& x_ using sin_call_b_ret = double; public: [[nodiscard]] static auto sin_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> sin_call_b_ret; +using func_b_ret = double; +public: [[nodiscard]] static auto func_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& ret_b) -> func_b_ret; + +using func_call_b_ret = double; +public: [[nodiscard]] static auto func_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> func_call_b_ret; + +using func_outer_call_b_ret = double; +public: [[nodiscard]] static auto func_outer_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> func_outer_call_b_ret; + public: ad_test_reverse() = default; public: ad_test_reverse(ad_test_reverse const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(ad_test_reverse const&) -> void = delete; -#line 247 "pure2-autodiff.cpp2" +#line 259 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 251 "pure2-autodiff.cpp2" +#line 263 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -493,15 +522,15 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 254 "pure2-autodiff.cpp2" +#line 266 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 260 "pure2-autodiff.cpp2" +#line 272 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void; -#line 267 "pure2-autodiff.cpp2" +#line 279 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -941,9 +970,9 @@ double temp_1_d {-x_d}; double r_d {0.0}; auto temp_1 {func_d(x, x_d, y, y_d)}; - double temp_2_d {temp_1.ret_d}; + double temp_2_d {cpp2::move(temp_1).ret_d}; - double temp_2 {cpp2::move(temp_1).ret}; + double temp_2 {func(x, y)}; r_d = temp_2 * x_d + x * cpp2::move(temp_2_d); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; @@ -954,9 +983,9 @@ auto temp_1 {func_d(x, x_d, y, y_d)}; double r_d {0.0}; auto temp_1 {func_outer_d(x, x_d, y, y_d)}; - double temp_2_d {temp_1.ret_d}; + double temp_2_d {cpp2::move(temp_1).ret_d}; - double temp_2 {cpp2::move(temp_1).ret}; + double temp_2 {func_outer(x, y)}; r_d = temp_2 * x_d + x * cpp2::move(temp_2_d); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; @@ -1151,12 +1180,19 @@ type_outer_d t_d {}; t_d.a_d = x_d; t.a = x; - auto temp_1 {CPP2_UFCS(add_d)(cpp2::move(t), cpp2::move(t_d), y, y_d)}; - r_d = temp_1.r_d; - r = cpp2::move(temp_1).r; + auto temp_1 {CPP2_UFCS(add_d)(t, cpp2::move(t_d), y, y_d)}; + r_d = cpp2::move(temp_1).r_d; + r = CPP2_UFCS(add)(cpp2::move(t), y); return { std::move(r), std::move(r_d) }; } + [[nodiscard]] auto func_outer_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& ret_b) -> func_outer_b_ret{ + double ret {0.0};ret = x + y; + x_b += ret_b; + y_b += ret_b; + ret_b = 0.0; + return ret; } + #line 196 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; @@ -1248,6 +1284,27 @@ type_outer_d t_d {}; r.construct(sin(x - y)); return std::move(r.value()); } +#line 248 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ + cpp2::impl::deferred_init ret; +#line 249 "pure2-autodiff.cpp2" + ret.construct(x + y); + return std::move(ret.value()); } + +#line 252 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ + cpp2::impl::deferred_init r; +#line 253 "pure2-autodiff.cpp2" + r.construct(x * func(x, y)); + return std::move(r.value()); } + +#line 256 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ + cpp2::impl::deferred_init r; +#line 257 "pure2-autodiff.cpp2" + r.construct(x * func_outer(x, y)); + return std::move(r.value()); } + [[nodiscard]] auto ad_test_reverse::add_1_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> add_1_b_ret{ double r {0.0};r = x + y; x_b += r_b; @@ -1383,13 +1440,46 @@ double temp_1_b {0.0}; temp_1_b = 0.0; return r; } -#line 248 "pure2-autodiff.cpp2" + [[nodiscard]] auto ad_test_reverse::func_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& ret_b) -> func_b_ret{ + double ret {0.0};ret = x + y; + x_b += ret_b; + y_b += ret_b; + ret_b = 0.0; + return ret; } + + [[nodiscard]] auto ad_test_reverse::func_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> func_call_b_ret{ + double r {0.0}; +double temp_2_b {0.0}; + + double temp_2 {func(x, y)}; + r = x * temp_2; + x_b += cpp2::move(temp_2) * r_b; + temp_2_b += x * r_b; + r_b = 0.0; + static_cast(func_b(x, x_b, y, y_b, temp_2_b)); + temp_2_b = 0.0; + return r; } + + [[nodiscard]] auto ad_test_reverse::func_outer_call_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b) -> func_outer_call_b_ret{ + double r {0.0}; +double temp_2_b {0.0}; + + double temp_2 {func_outer(x, y)}; + r = x * temp_2; + x_b += cpp2::move(temp_2) * r_b; + temp_2_b += x * r_b; + r_b = 0.0; + static_cast(func_outer_b(x, x_b, y, y_b, temp_2_b)); + temp_2_b = 0.0; + return r; } + +#line 260 "pure2-autodiff.cpp2" } -#line 251 "pure2-autodiff.cpp2" +#line 263 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 252 "pure2-autodiff.cpp2" +#line 264 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -1426,12 +1516,12 @@ double temp_1_d2 {x_d * x_d2 + x * x_d_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 256 "pure2-autodiff.cpp2" +#line 268 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 260 "pure2-autodiff.cpp2" +#line 272 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void{ r_b = 1.0; std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", y = " + cpp2::to_string(y) + ", r_b = " + cpp2::to_string(r_b) + ") = (r = " + cpp2::to_string(ret) + ", x_b = " + cpp2::to_string(x_b) + ", y_b = " + cpp2::to_string(y_b) + ")" << std::endl; @@ -1439,7 +1529,7 @@ auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in int{ double x {2.0}; @@ -1494,7 +1584,9 @@ auto main() -> int{ write_output_reverse("x * y / x", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_div_2_b(x, x_b, y, y_b, w_b)); write_output_reverse("x * (x + y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::mul_add_b(x, x_b, y, y_b, w_b)); write_output_reverse("x + x * y", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::add_mul_b(x, x_b, y, y_b, w_b)); - write_output_reverse("sin(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sin_call_b(x, x_b, cpp2::move(y), y_b, w_b)); + write_output_reverse("sin(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::sin_call_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * func(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::func_call_b(x, x_b, y, y_b, w_b)); + write_output_reverse("x * func_outer(x-y)", x, x_b, y, y_b, w_b, ad_name::ad_test_reverse::func_outer_call_b(x, x_b, cpp2::move(y), y_b, w_b)); static_cast(cpp2::move(x_b)); static_cast(cpp2::move(y_b)); diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index d6093d901..c297b8b72 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -577,7 +577,7 @@ ad_test:/* @autodiff @print */ type = { temp_1: _ = func_d(x, x_d, y, y_d); temp_2_d: double = temp_1.ret_d; - temp_2: double = temp_1.ret; + temp_2: double = func(x, y); r_d = temp_2 * x_d + x * temp_2_d; r = x * temp_2; return; @@ -595,7 +595,7 @@ ad_test:/* @autodiff @print */ type = { temp_1: _ = func_outer_d(x, x_d, y, y_d); temp_2_d: double = temp_1.ret_d; - temp_2: double = temp_1.ret; + temp_2: double = func_outer(x, y); r_d = temp_2 * x_d + x * temp_2_d; r = x * temp_2; return; @@ -885,7 +885,7 @@ ad_test:/* @autodiff @print */ type = t.a = x; temp_1: _ = t.add_d(t_d, y, y_d); r_d = temp_1.r_d; - r = temp_1.r; + r = t.add(y); return; } } @@ -1010,6 +1010,33 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = return; } + func:( + in x: double, + in y: double, + ) -> (out ret: double, ) = + { + ret = x + y; + return; + } + + func_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func(x, y); + return; + } + + func_outer_call:( + in x: double, + in y: double, + ) -> (out r: double, ) = + { + r = x * func_outer(x, y); + return; + } + add_1_b:( in x: double, inout x_b: double, @@ -1236,6 +1263,59 @@ ad_test_reverse:/* @autodiff<"reverse"> @print */ type = temp_1_b = 0.0; return; } + + func_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout ret_b: double, + ) -> (out ret: double = 0.0, ) = + { + ret = x + y; + x_b += ret_b; + y_b += ret_b; + ret_b = 0.0; + return; + } + + func_call_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_2_b: double = 0.0; + temp_2: double = func(x, y); + r = x * temp_2; + x_b += temp_2 * r_b; + temp_2_b += x * r_b; + r_b = 0.0; + _ = func_b(x, x_b, y, y_b, temp_2_b); + temp_2_b = 0.0; + return; + } + + func_outer_call_b:( + in x: double, + inout x_b: double, + in y: double, + inout y_b: double, + inout r_b: double, + ) -> (out r: double = 0.0, ) = + { + temp_2_b: double = 0.0; + temp_2: double = func_outer(x, y); + r = x * temp_2; + x_b += temp_2 * r_b; + temp_2_b += x * r_b; + r_b = 0.0; + _ = func_outer_b(x, x_b, y, y_b, temp_2_b); + temp_2_b = 0.0; + return; + } } diff --git a/source/reflect.h b/source/reflect.h index 2dcb74b96..bfcfe792e 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -137,83 +137,83 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 5333 "reflect.h2" +#line 5362 "reflect.h2" class autodiff_stmt_handler; -#line 5628 "reflect.h2" +#line 5657 "reflect.h2" class autodiff_declaration_handler; -#line 5973 "reflect.h2" +#line 6002 "reflect.h2" class expression_flags; -#line 5989 "reflect.h2" +#line 6018 "reflect.h2" class regex_token; -#line 6016 "reflect.h2" +#line 6045 "reflect.h2" class regex_token_check; -#line 6037 "reflect.h2" +#line 6066 "reflect.h2" class regex_token_code; -#line 6058 "reflect.h2" +#line 6087 "reflect.h2" class regex_token_empty; -#line 6076 "reflect.h2" +#line 6105 "reflect.h2" class regex_token_list; -#line 6128 "reflect.h2" +#line 6157 "reflect.h2" class parse_context_group_state; -#line 6189 "reflect.h2" +#line 6218 "reflect.h2" class parse_context_branch_reset_state; -#line 6232 "reflect.h2" +#line 6261 "reflect.h2" class parse_context; -#line 6633 "reflect.h2" +#line 6662 "reflect.h2" class generation_function_context; -#line 6651 "reflect.h2" +#line 6680 "reflect.h2" class generation_context; -#line 6850 "reflect.h2" +#line 6879 "reflect.h2" class alternative_token; -#line 6865 "reflect.h2" +#line 6894 "reflect.h2" class alternative_token_gen; -#line 6930 "reflect.h2" +#line 6959 "reflect.h2" class any_token; -#line 6947 "reflect.h2" +#line 6976 "reflect.h2" class atomic_group_token; -#line 6977 "reflect.h2" +#line 7006 "reflect.h2" class char_token; -#line 7092 "reflect.h2" +#line 7121 "reflect.h2" class class_token; -#line 7316 "reflect.h2" +#line 7345 "reflect.h2" class group_ref_token; -#line 7453 "reflect.h2" +#line 7482 "reflect.h2" class group_token; -#line 7800 "reflect.h2" +#line 7829 "reflect.h2" class lookahead_lookbehind_token; -#line 7895 "reflect.h2" +#line 7924 "reflect.h2" class range_token; -#line 8052 "reflect.h2" +#line 8081 "reflect.h2" class special_range_token; -#line 8138 "reflect.h2" +#line 8167 "reflect.h2" template class regex_generator; -#line 8401 "reflect.h2" +#line 8430 "reflect.h2" } } @@ -2045,165 +2045,165 @@ public: primal_fwd_rws_name(); #line 4878 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 5029 "reflect.h2" +#line 5058 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5074 "reflect.h2" +#line 5103 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5078 "reflect.h2" +#line 5107 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5082 "reflect.h2" +#line 5111 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5086 "reflect.h2" +#line 5115 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5090 "reflect.h2" +#line 5119 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5094 "reflect.h2" +#line 5123 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5098 "reflect.h2" +#line 5127 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5102 "reflect.h2" +#line 5131 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5106 "reflect.h2" +#line 5135 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5110 "reflect.h2" +#line 5139 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5114 "reflect.h2" +#line 5143 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5118 "reflect.h2" +#line 5147 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5149 "reflect.h2" +#line 5178 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5236 "reflect.h2" +#line 5265 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5240 "reflect.h2" +#line 5269 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5256 "reflect.h2" +#line 5285 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5296 "reflect.h2" +#line 5325 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5331 "reflect.h2" +#line 5360 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5337 "reflect.h2" +#line 5366 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5346 "reflect.h2" +#line 5375 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5351 "reflect.h2" +#line 5380 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5356 "reflect.h2" +#line 5385 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5407 "reflect.h2" +#line 5436 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5412 "reflect.h2" +#line 5441 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5417 "reflect.h2" +#line 5446 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5422 "reflect.h2" +#line 5451 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5430 "reflect.h2" +#line 5459 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5447 "reflect.h2" +#line 5476 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5497 "reflect.h2" +#line 5526 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5508 "reflect.h2" +#line 5537 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5512 "reflect.h2" +#line 5541 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5537 "reflect.h2" +#line 5566 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5541 "reflect.h2" +#line 5570 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5545 "reflect.h2" +#line 5574 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5549 "reflect.h2" +#line 5578 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5553 "reflect.h2" +#line 5582 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5557 "reflect.h2" +#line 5586 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5561 "reflect.h2" +#line 5590 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5565 "reflect.h2" +#line 5594 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5569 "reflect.h2" +#line 5598 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5573 "reflect.h2" +#line 5602 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5577 "reflect.h2" +#line 5606 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5581 "reflect.h2" +#line 5610 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5585 "reflect.h2" +#line 5614 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5590 "reflect.h2" +#line 5619 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5622 "reflect.h2" +#line 5651 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5626 "reflect.h2" +#line 5655 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5632 "reflect.h2" +#line 5661 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2213,37 +2213,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5644 "reflect.h2" +#line 5673 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5649 "reflect.h2" +#line 5678 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5807 "reflect.h2" +#line 5836 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5835 "reflect.h2" +#line 5864 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5859 "reflect.h2" +#line 5888 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5864 "reflect.h2" +#line 5893 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5867 "reflect.h2" +#line 5896 "reflect.h2" }; -#line 5870 "reflect.h2" +#line 5899 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 5969 "reflect.h2" +#line 5998 "reflect.h2" using error_func = std::function x)>; -#line 5973 "reflect.h2" +#line 6002 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2278,20 +2278,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 5981 "reflect.h2" +#line 6010 "reflect.h2" }; -#line 5989 "reflect.h2" +#line 6018 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 5997 "reflect.h2" +#line 6026 "reflect.h2" public: explicit regex_token(); -#line 6002 "reflect.h2" +#line 6031 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2303,103 +2303,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 6008 "reflect.h2" +#line 6037 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 6014 "reflect.h2" +#line 6043 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 6020 "reflect.h2" +#line 6049 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 6027 "reflect.h2" +#line 6056 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6031 "reflect.h2" +#line 6060 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6032 "reflect.h2" +#line 6061 "reflect.h2" }; -#line 6035 "reflect.h2" +#line 6064 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6041 "reflect.h2" +#line 6070 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6048 "reflect.h2" +#line 6077 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6052 "reflect.h2" +#line 6081 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6053 "reflect.h2" +#line 6082 "reflect.h2" }; -#line 6056 "reflect.h2" +#line 6085 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6062 "reflect.h2" +#line 6091 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6066 "reflect.h2" +#line 6095 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6070 "reflect.h2" +#line 6099 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6071 "reflect.h2" +#line 6100 "reflect.h2" }; -#line 6074 "reflect.h2" +#line 6103 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6080 "reflect.h2" +#line 6109 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6087 "reflect.h2" +#line 6116 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6093 "reflect.h2" +#line 6122 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6099 "reflect.h2" +#line 6128 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6107 "reflect.h2" +#line 6136 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2407,10 +2407,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6119 "reflect.h2" +#line 6148 "reflect.h2" }; -#line 6122 "reflect.h2" +#line 6151 "reflect.h2" // // Parse and generation context. // @@ -2426,33 +2426,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6142 "reflect.h2" +#line 6171 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6149 "reflect.h2" +#line 6178 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6161 "reflect.h2" +#line 6190 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6166 "reflect.h2" +#line 6195 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6170 "reflect.h2" +#line 6199 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6184 "reflect.h2" +#line 6213 "reflect.h2" }; -#line 6187 "reflect.h2" +#line 6216 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2465,25 +2465,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6205 "reflect.h2" +#line 6234 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6211 "reflect.h2" +#line 6240 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6218 "reflect.h2" +#line 6247 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6225 "reflect.h2" +#line 6254 "reflect.h2" }; -#line 6228 "reflect.h2" +#line 6257 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2499,7 +2499,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6244 "reflect.h2" +#line 6273 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2507,64 +2507,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6255 "reflect.h2" +#line 6284 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6268 "reflect.h2" +#line 6297 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6276 "reflect.h2" +#line 6305 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6280 "reflect.h2" +#line 6309 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6284 "reflect.h2" +#line 6313 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6296 "reflect.h2" +#line 6325 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6303 "reflect.h2" +#line 6332 "reflect.h2" public: auto next_alternative() & -> void; -#line 6309 "reflect.h2" +#line 6338 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6315 "reflect.h2" +#line 6344 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6319 "reflect.h2" +#line 6348 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6330 "reflect.h2" +#line 6359 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6334 "reflect.h2" +#line 6363 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6340 "reflect.h2" +#line 6369 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6344 "reflect.h2" +#line 6373 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6351 "reflect.h2" +#line 6380 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6362 "reflect.h2" +#line 6391 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2572,51 +2572,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6406 "reflect.h2" +#line 6435 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6418 "reflect.h2" +#line 6447 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6431 "reflect.h2" +#line 6460 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6454 "reflect.h2" +#line 6483 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6471 "reflect.h2" +#line 6500 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6492 "reflect.h2" +#line 6521 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6502 "reflect.h2" +#line 6531 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6506 "reflect.h2" +#line 6535 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6562 "reflect.h2" +#line 6591 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6601 "reflect.h2" +#line 6630 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6616 "reflect.h2" +#line 6645 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2628,10 +2628,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6627 "reflect.h2" +#line 6656 "reflect.h2" }; -#line 6630 "reflect.h2" +#line 6659 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2641,16 +2641,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6644 "reflect.h2" +#line 6673 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6647 "reflect.h2" +#line 6676 "reflect.h2" }; -#line 6650 "reflect.h2" +#line 6679 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2670,68 +2670,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6672 "reflect.h2" +#line 6701 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6678 "reflect.h2" +#line 6707 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6687 "reflect.h2" +#line 6716 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6698 "reflect.h2" +#line 6727 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6705 "reflect.h2" +#line 6734 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6725 "reflect.h2" +#line 6754 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6735 "reflect.h2" +#line 6764 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6758 "reflect.h2" +#line 6787 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6766 "reflect.h2" +#line 6795 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6770 "reflect.h2" +#line 6799 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6776 "reflect.h2" +#line 6805 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6782 "reflect.h2" +#line 6811 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6792 "reflect.h2" +#line 6821 "reflect.h2" public: auto finish_context() & -> void; -#line 6800 "reflect.h2" +#line 6829 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6806 "reflect.h2" +#line 6835 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6810 "reflect.h2" +#line 6839 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6814 "reflect.h2" +#line 6843 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6838 "reflect.h2" +#line 6867 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2739,7 +2739,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6844 "reflect.h2" +#line 6873 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2759,27 +2759,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6863 "reflect.h2" +#line 6892 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6869 "reflect.h2" +#line 6898 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6876 "reflect.h2" +#line 6905 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6893 "reflect.h2" +#line 6922 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6900 "reflect.h2" +#line 6929 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6913 "reflect.h2" +#line 6942 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2787,19 +2787,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6925 "reflect.h2" +#line 6954 "reflect.h2" }; -#line 6928 "reflect.h2" +#line 6957 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6934 "reflect.h2" +#line 6963 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6938 "reflect.h2" +#line 6967 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2807,7 +2807,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6943 "reflect.h2" +#line 6972 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2815,17 +2815,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6951 "reflect.h2" +#line 6980 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 6962 "reflect.h2" +#line 6991 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6970 "reflect.h2" +#line 6999 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2833,7 +2833,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 6973 "reflect.h2" +#line 7002 "reflect.h2" }; // Regex syntax: a @@ -2841,34 +2841,34 @@ class atomic_group_token class char_token : public regex_token { -#line 6981 "reflect.h2" +#line 7010 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6990 "reflect.h2" +#line 7019 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 6996 "reflect.h2" +#line 7025 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7000 "reflect.h2" +#line 7029 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7023 "reflect.h2" +#line 7052 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7044 "reflect.h2" +#line 7073 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7062 "reflect.h2" +#line 7091 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7077 "reflect.h2" +#line 7106 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7083 "reflect.h2" +#line 7112 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2876,33 +2876,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7087 "reflect.h2" +#line 7116 "reflect.h2" }; -#line 7090 "reflect.h2" +#line 7119 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7096 "reflect.h2" +#line 7125 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7108 "reflect.h2" +#line 7137 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7234 "reflect.h2" +#line 7263 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7243 "reflect.h2" +#line 7272 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7248 "reflect.h2" +#line 7277 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2910,20 +2910,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7255 "reflect.h2" +#line 7284 "reflect.h2" }; -#line 7258 "reflect.h2" +#line 7287 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7299 "reflect.h2" +#line 7328 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7310 "reflect.h2" +#line 7339 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2933,20 +2933,20 @@ class class_token class group_ref_token : public regex_token { -#line 7320 "reflect.h2" +#line 7349 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7332 "reflect.h2" +#line 7361 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7433 "reflect.h2" +#line 7462 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7437 "reflect.h2" +#line 7466 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2954,10 +2954,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7440 "reflect.h2" +#line 7469 "reflect.h2" }; -#line 7443 "reflect.h2" +#line 7472 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2971,29 +2971,29 @@ class group_ref_token class group_token : public regex_token { -#line 7457 "reflect.h2" +#line 7486 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7479 "reflect.h2" +#line 7508 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7493 "reflect.h2" +#line 7522 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7652 "reflect.h2" +#line 7681 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7660 "reflect.h2" +#line 7689 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7678 "reflect.h2" +#line 7707 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7709 "reflect.h2" +#line 7738 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -3002,25 +3002,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7716 "reflect.h2" +#line 7745 "reflect.h2" }; -#line 7719 "reflect.h2" +#line 7748 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7760 "reflect.h2" +#line 7789 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7780 "reflect.h2" +#line 7809 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7796 "reflect.h2" +#line 7825 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3028,20 +3028,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7804 "reflect.h2" +#line 7833 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7813 "reflect.h2" +#line 7842 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7824 "reflect.h2" +#line 7853 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7831 "reflect.h2" +#line 7860 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3049,26 +3049,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7834 "reflect.h2" +#line 7863 "reflect.h2" }; -#line 7837 "reflect.h2" +#line 7866 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7865 "reflect.h2" +#line 7894 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7893 "reflect.h2" +#line 7922 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7899 "reflect.h2" +#line 7928 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3078,22 +3078,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7979 "reflect.h2" +#line 8008 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 7991 "reflect.h2" +#line 8020 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 8004 "reflect.h2" +#line 8033 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 8023 "reflect.h2" +#line 8052 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8033 "reflect.h2" +#line 8062 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8044 "reflect.h2" +#line 8073 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3101,16 +3101,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8047 "reflect.h2" +#line 8076 "reflect.h2" }; -#line 8050 "reflect.h2" +#line 8079 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8056 "reflect.h2" +#line 8085 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3119,7 +3119,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8086 "reflect.h2" +#line 8115 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3128,14 +3128,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8108 "reflect.h2" +#line 8137 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8130 "reflect.h2" +#line 8159 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3156,24 +3156,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8153 "reflect.h2" +#line 8182 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8188 "reflect.h2" +#line 8217 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8202 "reflect.h2" +#line 8231 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8214 "reflect.h2" +#line 8243 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8269 "reflect.h2" +#line 8298 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3184,7 +3184,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8401 "reflect.h2" +#line 8430 "reflect.h2" } } @@ -8859,7 +8859,7 @@ auto i{0}; } #line 4942 "reflect.h2" - if (handle_special_function(object, object_d, cpp2::move(object_b), function_name, args)) { + if (handle_special_function(object, object_d, object_b, function_name, args)) { return ; } @@ -8868,30 +8868,40 @@ auto i{0}; return ; } + std::string call_primal {""}; + std::string call_fwd {""}; + std::string call_rws {""}; + // All arguments have now been handled. Form the function call std::string ret_temp {""}; if (has_return) { ret_temp = CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx))); - diff += "" + cpp2::to_string(ret_temp) + " := "; + call_fwd += "" + cpp2::to_string(ret_temp) + " := "; } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. if (!(CPP2_UFCS(empty)(object))) {// Prepend object call - diff += "" + cpp2::to_string(object) + "."; + call_primal += "" + cpp2::to_string(object) + "."; + call_fwd += "" + cpp2::to_string(object) + "."; + call_rws += "" + cpp2::to_string(object) + "."; } - diff += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "("; + call_primal += "" + cpp2::to_string(function_name) + "("; + call_fwd += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "("; + call_rws += "" + cpp2::to_string(function_name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "("; if (!(CPP2_UFCS(empty)(object))) {// Add this_d argument. - diff += "" + cpp2::to_string(cpp2::move(object_d)) + ", "; + call_fwd += "" + cpp2::to_string(cpp2::move(object_d)) + ", "; + call_rws += "" + cpp2::to_string(cpp2::move(object_b)) + ", "; } for ( auto const& arg : cpp2::move(args) ) { + // TODO: Add taylor reverse handling. + call_primal += "" + cpp2::to_string(arg.primal) + ", "; + call_fwd += "" + cpp2::to_string(arg.primal) + ", "; + call_rws += "" + cpp2::to_string(arg.primal) + ", "; if (arg.active) { - diff += "" + cpp2::to_string(arg.primal) + ", " + cpp2::to_string(arg.fwd) + ", "; - } - else { - diff += "" + cpp2::to_string(arg.primal) + ", "; + call_fwd += "" + cpp2::to_string(arg.fwd) + ", "; + call_rws += "" + cpp2::to_string(arg.rws) + ", "; } } - diff += ");\n"; if (has_return) { std::vector functions {}; @@ -8938,15 +8948,34 @@ auto i{0}; } std::string ret_name_d {ret_name + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix}; + std::string ret_name_b {cpp2::move(ret_name) + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; + + call_rws += "_rb_, "; + + call_primal += ")"; + call_fwd += ");\n"; + call_rws += ");\n"; - primal_expr = "" + cpp2::to_string(ret_temp) + "." + cpp2::to_string(cpp2::move(ret_name)) + ""; + CPP2_UFCS(add_forward)(diff, cpp2::move(call_fwd)); + + primal_expr = cpp2::move(call_primal); fwd_expr = "" + cpp2::to_string(cpp2::move(ret_temp)) + "." + cpp2::to_string(cpp2::move(ret_name_d)) + ""; + rws_expr = "_ = " + cpp2::to_string(cpp2::move(call_rws)) + ""; + } + else { + call_primal += ");\n"; + call_fwd += ");\n"; + call_rws += ");\n"; + + CPP2_UFCS(add_forward)(diff, cpp2::move(call_fwd)); + CPP2_UFCS(add_reverse_primal)(diff, cpp2::move(call_primal)); + CPP2_UFCS(add_reverse_backprop)(diff, cpp2::move(call_rws)); } // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 5029 "reflect.h2" +#line 5058 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -8974,7 +9003,7 @@ auto i{0}; { auto i{1}; -#line 5055 "reflect.h2" +#line 5084 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -8988,7 +9017,7 @@ auto i{1}; } } -#line 5067 "reflect.h2" +#line 5096 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); rws_expr = cpp2::move(code_rws); @@ -8996,62 +9025,62 @@ auto i{1}; return true; } -#line 5074 "reflect.h2" +#line 5103 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5078 "reflect.h2" +#line 5107 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5082 "reflect.h2" +#line 5111 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5086 "reflect.h2" +#line 5115 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5090 "reflect.h2" +#line 5119 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5094 "reflect.h2" +#line 5123 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5098 "reflect.h2" +#line 5127 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5102 "reflect.h2" +#line 5131 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5106 "reflect.h2" +#line 5135 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5110 "reflect.h2" +#line 5139 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5114 "reflect.h2" +#line 5143 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5118 "reflect.h2" +#line 5147 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9083,7 +9112,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5149 "reflect.h2" +#line 5178 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9154,7 +9183,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5220 "reflect.h2" +#line 5249 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9171,12 +9200,12 @@ auto i{1}; } } -#line 5236 "reflect.h2" +#line 5265 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5240 "reflect.h2" +#line 5269 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9193,7 +9222,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5256 "reflect.h2" +#line 5285 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9202,7 +9231,7 @@ auto i{1}; { auto i{0}; -#line 5263 "reflect.h2" +#line 5292 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9217,7 +9246,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5276 "reflect.h2" +#line 5305 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9238,7 +9267,7 @@ auto i{0}; } } -#line 5296 "reflect.h2" +#line 5325 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9275,26 +9304,26 @@ auto i{0}; }}}} } -#line 5341 "reflect.h2" +#line 5370 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5344 "reflect.h2" +#line 5373 "reflect.h2" } -#line 5346 "reflect.h2" +#line 5375 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5351 "reflect.h2" +#line 5380 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5356 "reflect.h2" +#line 5385 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9345,22 +9374,22 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5407 "reflect.h2" +#line 5436 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5412 "reflect.h2" +#line 5441 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5417 "reflect.h2" +#line 5446 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ base::traverse(stmt); } -#line 5422 "reflect.h2" +#line 5451 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // Brackets are handled by the diff += "{\n"; @@ -9368,7 +9397,7 @@ auto i{0}; diff += "}\n"; } -#line 5430 "reflect.h2" +#line 5459 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9385,7 +9414,7 @@ auto i{0}; } } -#line 5447 "reflect.h2" +#line 5476 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition @@ -9435,7 +9464,7 @@ auto i{0}; }} } -#line 5497 "reflect.h2" +#line 5526 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9447,12 +9476,12 @@ auto i{0}; } } -#line 5508 "reflect.h2" +#line 5537 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5512 "reflect.h2" +#line 5541 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9478,73 +9507,73 @@ auto i{0}; } } -#line 5537 "reflect.h2" +#line 5566 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5541 "reflect.h2" +#line 5570 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5545 "reflect.h2" +#line 5574 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5549 "reflect.h2" +#line 5578 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5553 "reflect.h2" +#line 5582 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5557 "reflect.h2" +#line 5586 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5561 "reflect.h2" +#line 5590 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5565 "reflect.h2" +#line 5594 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5569 "reflect.h2" +#line 5598 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5573 "reflect.h2" +#line 5602 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5577 "reflect.h2" +#line 5606 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5581 "reflect.h2" +#line 5610 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5585 "reflect.h2" +#line 5614 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5590 "reflect.h2" +#line 5619 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9553,7 +9582,7 @@ auto i{0}; { auto i{0}; -#line 5597 "reflect.h2" +#line 5626 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9568,7 +9597,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5610 "reflect.h2" +#line 5639 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9581,27 +9610,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5622 "reflect.h2" +#line 5651 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5639 "reflect.h2" +#line 5668 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5642 "reflect.h2" +#line 5671 "reflect.h2" } -#line 5644 "reflect.h2" +#line 5673 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5649 "reflect.h2" +#line 5678 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9731,10 +9760,10 @@ auto i{0}; return ; } -#line 5779 "reflect.h2" +#line 5808 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5782 "reflect.h2" +#line 5811 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9759,7 +9788,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5807 "reflect.h2" +#line 5836 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9787,7 +9816,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5835 "reflect.h2" +#line 5864 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9811,17 +9840,17 @@ auto i{0}; } } -#line 5859 "reflect.h2" +#line 5888 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5864 "reflect.h2" +#line 5893 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5870 "reflect.h2" +#line 5899 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9997,7 +10026,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 5955 "reflect.h2" +#line 5984 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -10013,11 +10042,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 5971 "reflect.h2" +#line 6000 "reflect.h2" // Possible modifiers for a regular expression. // -#line 5975 "reflect.h2" +#line 6004 "reflect.h2" // mod: i // mod: m // mod: s @@ -10025,116 +10054,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 5984 "reflect.h2" +#line 6013 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 5993 "reflect.h2" +#line 6022 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 5995 "reflect.h2" +#line 6024 "reflect.h2" } -#line 5997 "reflect.h2" +#line 6026 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 5999 "reflect.h2" +#line 6028 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 6005 "reflect.h2" +#line 6034 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 6006 "reflect.h2" +#line 6035 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 6007 "reflect.h2" +#line 6036 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 6022 "reflect.h2" +#line 6051 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 6025 "reflect.h2" +#line 6054 "reflect.h2" } -#line 6027 "reflect.h2" +#line 6056 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 6031 "reflect.h2" +#line 6060 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6043 "reflect.h2" +#line 6072 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6046 "reflect.h2" +#line 6075 "reflect.h2" } -#line 6048 "reflect.h2" +#line 6077 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6052 "reflect.h2" +#line 6081 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6062 "reflect.h2" +#line 6091 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6064 "reflect.h2" +#line 6093 "reflect.h2" } -#line 6066 "reflect.h2" +#line 6095 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6070 "reflect.h2" +#line 6099 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6082 "reflect.h2" +#line 6111 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6085 "reflect.h2" +#line 6114 "reflect.h2" } -#line 6087 "reflect.h2" +#line 6116 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6093 "reflect.h2" +#line 6122 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6099 "reflect.h2" +#line 6128 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10143,7 +10172,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6107 "reflect.h2" +#line 6136 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10159,7 +10188,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6135 "reflect.h2" +#line 6164 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10167,14 +10196,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6143 "reflect.h2" +#line 6172 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6150 "reflect.h2" +#line 6179 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10186,15 +10215,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6162 "reflect.h2" +#line 6191 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6167 "reflect.h2" +#line 6196 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6171 "reflect.h2" +#line 6200 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10215,7 +10244,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6197 "reflect.h2" +#line 6226 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10224,20 +10253,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6206 "reflect.h2" +#line 6235 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6212 "reflect.h2" +#line 6241 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6219 "reflect.h2" +#line 6248 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10252,16 +10281,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6249 "reflect.h2" +#line 6278 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6253 "reflect.h2" +#line 6282 "reflect.h2" } -#line 6259 "reflect.h2" +#line 6288 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10271,7 +10300,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6269 "reflect.h2" +#line 6298 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10279,17 +10308,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6276 "reflect.h2" +#line 6305 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6280 "reflect.h2" +#line 6309 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6287 "reflect.h2" +#line 6316 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10299,7 +10328,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6296 "reflect.h2" +#line 6325 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10307,24 +10336,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6303 "reflect.h2" +#line 6332 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6311 "reflect.h2" +#line 6340 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6315 "reflect.h2" +#line 6344 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6319 "reflect.h2" +#line 6348 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10336,22 +10365,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6330 "reflect.h2" +#line 6359 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6336 "reflect.h2" +#line 6365 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6340 "reflect.h2" +#line 6369 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6344 "reflect.h2" +#line 6373 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10359,7 +10388,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6351 "reflect.h2" +#line 6380 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10371,10 +10400,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6364 "reflect.h2" +#line 6393 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6367 "reflect.h2" +#line 6396 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10414,7 +10443,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6407 "reflect.h2" +#line 6436 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10426,14 +10455,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6418 "reflect.h2" +#line 6447 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6419 "reflect.h2" +#line 6448 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6420 "reflect.h2" +#line 6449 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6422 "reflect.h2" +#line 6451 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10443,10 +10472,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6431 "reflect.h2" +#line 6460 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6433 "reflect.h2" +#line 6462 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10468,14 +10497,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6454 "reflect.h2" +#line 6483 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6455 "reflect.h2" +#line 6484 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6456 "reflect.h2" +#line 6485 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6458 "reflect.h2" +#line 6487 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10489,7 +10518,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6471 "reflect.h2" +#line 6500 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10511,7 +10540,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6492 "reflect.h2" +#line 6521 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10522,12 +10551,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6502 "reflect.h2" +#line 6531 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6503 "reflect.h2" +#line 6532 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6508 "reflect.h2" +#line 6537 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10582,7 +10611,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6562 "reflect.h2" +#line 6591 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10622,7 +10651,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6601 "reflect.h2" +#line 6630 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10638,21 +10667,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6618 "reflect.h2" +#line 6647 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6619 "reflect.h2" +#line 6648 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6620 "reflect.h2" +#line 6649 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6622 "reflect.h2" +#line 6651 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6637 "reflect.h2" +#line 6666 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10660,7 +10689,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6644 "reflect.h2" +#line 6673 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10670,22 +10699,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6662 "reflect.h2" +#line 6691 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6667 "reflect.h2" +#line 6696 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6673 "reflect.h2" +#line 6702 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6679 "reflect.h2" +#line 6708 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10694,7 +10723,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6687 "reflect.h2" +#line 6716 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10706,7 +10735,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6698 "reflect.h2" +#line 6727 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10714,7 +10743,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6705 "reflect.h2" +#line 6734 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10735,7 +10764,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6726 "reflect.h2" +#line 6755 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10745,7 +10774,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6736 "reflect.h2" +#line 6765 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10768,33 +10797,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6760 "reflect.h2" +#line 6789 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6766 "reflect.h2" +#line 6795 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6770 "reflect.h2" +#line 6799 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6776 "reflect.h2" +#line 6805 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6784 "reflect.h2" +#line 6813 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10803,7 +10832,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6792 "reflect.h2" +#line 6821 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10812,22 +10841,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6802 "reflect.h2" +#line 6831 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6806 "reflect.h2" +#line 6835 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6810 "reflect.h2" +#line 6839 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6814 "reflect.h2" +#line 6843 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10851,18 +10880,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6839 "reflect.h2" +#line 6868 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6854 "reflect.h2" +#line 6883 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6856 "reflect.h2" +#line 6885 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10873,15 +10902,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6871 "reflect.h2" +#line 6900 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6874 "reflect.h2" +#line 6903 "reflect.h2" } -#line 6876 "reflect.h2" +#line 6905 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10899,7 +10928,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6893 "reflect.h2" +#line 6922 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10907,7 +10936,7 @@ generation_function_context::generation_function_context(){} } } -#line 6900 "reflect.h2" +#line 6929 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10921,7 +10950,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6913 "reflect.h2" +#line 6942 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10937,14 +10966,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6934 "reflect.h2" +#line 6963 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6936 "reflect.h2" +#line 6965 "reflect.h2" } -#line 6938 "reflect.h2" +#line 6967 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -10953,11 +10982,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 6953 "reflect.h2" +#line 6982 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 6955 "reflect.h2" +#line 6984 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -10965,7 +10994,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6962 "reflect.h2" +#line 6991 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -10974,37 +11003,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 6970 "reflect.h2" +#line 6999 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 6984 "reflect.h2" +#line 7013 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6988 "reflect.h2" +#line 7017 "reflect.h2" } -#line 6990 "reflect.h2" +#line 7019 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 6994 "reflect.h2" +#line 7023 "reflect.h2" } -#line 6996 "reflect.h2" +#line 7025 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 7000 "reflect.h2" +#line 7029 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -11013,14 +11042,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 7006 "reflect.h2" +#line 7035 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 7011 "reflect.h2" +#line 7040 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -11033,7 +11062,7 @@ size_t i{0}; } } -#line 7023 "reflect.h2" +#line 7052 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11055,7 +11084,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7044 "reflect.h2" +#line 7073 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11074,7 +11103,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7062 "reflect.h2" +#line 7091 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11090,14 +11119,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7077 "reflect.h2" +#line 7106 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7083 "reflect.h2" +#line 7112 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11105,19 +11134,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7100 "reflect.h2" +#line 7129 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7101 "reflect.h2" +#line 7130 "reflect.h2" { -#line 7106 "reflect.h2" +#line 7135 "reflect.h2" } -#line 7109 "reflect.h2" +#line 7138 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11243,7 +11272,7 @@ size_t i{0}; ); } -#line 7234 "reflect.h2" +#line 7263 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11253,13 +11282,13 @@ size_t i{0}; ); } -#line 7243 "reflect.h2" +#line 7272 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7248 "reflect.h2" +#line 7277 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11270,12 +11299,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7260 "reflect.h2" +#line 7289 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7265 "reflect.h2" +#line 7294 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11309,7 +11338,7 @@ size_t i{0}; } -#line 7301 "reflect.h2" +#line 7330 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11318,19 +11347,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7324 "reflect.h2" +#line 7353 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7325 "reflect.h2" +#line 7354 "reflect.h2" { -#line 7330 "reflect.h2" +#line 7359 "reflect.h2" } -#line 7332 "reflect.h2" +#line 7361 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11432,19 +11461,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7433 "reflect.h2" +#line 7462 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7437 "reflect.h2" +#line 7466 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7461 "reflect.h2" +#line 7490 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11463,7 +11492,7 @@ size_t i{0}; return r; } -#line 7479 "reflect.h2" +#line 7508 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11478,7 +11507,7 @@ size_t i{0}; return r; } -#line 7493 "reflect.h2" +#line 7522 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11638,7 +11667,7 @@ size_t i{0}; } } -#line 7652 "reflect.h2" +#line 7681 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11647,7 +11676,7 @@ size_t i{0}; return r; } -#line 7660 "reflect.h2" +#line 7689 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11666,7 +11695,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7678 "reflect.h2" +#line 7707 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11698,7 +11727,7 @@ size_t i{0}; } } -#line 7709 "reflect.h2" +#line 7738 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11709,7 +11738,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7721 "reflect.h2" +#line 7750 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11748,7 +11777,7 @@ size_t i{0}; return r; } -#line 7762 "reflect.h2" +#line 7791 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11766,7 +11795,7 @@ size_t i{0}; }} } -#line 7782 "reflect.h2" +#line 7811 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11780,16 +11809,16 @@ size_t i{0}; } } -#line 7808 "reflect.h2" +#line 7837 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7811 "reflect.h2" +#line 7840 "reflect.h2" } -#line 7813 "reflect.h2" +#line 7842 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11801,7 +11830,7 @@ size_t i{0}; } } -#line 7824 "reflect.h2" +#line 7853 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11809,14 +11838,14 @@ size_t i{0}; return r; } -#line 7831 "reflect.h2" +#line 7860 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7839 "reflect.h2" +#line 7868 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11842,7 +11871,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7867 "reflect.h2" +#line 7896 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11868,11 +11897,11 @@ size_t i{0}; return r; } -#line 7904 "reflect.h2" +#line 7933 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7906 "reflect.h2" +#line 7935 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11946,7 +11975,7 @@ size_t i{0}; return nullptr; } -#line 7979 "reflect.h2" +#line 8008 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -11959,7 +11988,7 @@ size_t i{0}; }} } -#line 7991 "reflect.h2" +#line 8020 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -11973,7 +12002,7 @@ size_t i{0}; }} } -#line 8004 "reflect.h2" +#line 8033 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -11993,7 +12022,7 @@ size_t i{0}; return r; } -#line 8023 "reflect.h2" +#line 8052 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -12004,7 +12033,7 @@ size_t i{0}; return r; } -#line 8033 "reflect.h2" +#line 8062 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -12016,14 +12045,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8044 "reflect.h2" +#line 8073 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8056 "reflect.h2" +#line 8085 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12047,7 +12076,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8080 "reflect.h2" +#line 8109 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12057,7 +12086,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8092 "reflect.h2" +#line 8121 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12073,7 +12102,7 @@ size_t i{0}; } } -#line 8112 "reflect.h2" +#line 8141 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12091,15 +12120,15 @@ size_t i{0}; }} } -#line 8148 "reflect.h2" +#line 8177 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8151 "reflect.h2" +#line 8180 "reflect.h2" } -#line 8153 "reflect.h2" +#line 8182 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12135,7 +12164,7 @@ size_t i{0}; return source; } -#line 8188 "reflect.h2" +#line 8217 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12151,7 +12180,7 @@ size_t i{0}; } } -#line 8204 "reflect.h2" +#line 8233 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12160,7 +12189,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12215,7 +12244,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8273 "reflect.h2" +#line 8302 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12343,7 +12372,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8401 "reflect.h2" +#line 8430 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 848c46b6e..d3957a3ef 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4948,30 +4948,40 @@ autodiff_expression_handler: type = { return; } + call_primal: std::string = ""; + call_fwd : std::string = ""; + call_rws : std::string = ""; + // All arguments have now been handled. Form the function call ret_temp : std::string = ""; if has_return { ret_temp = ctx*.gen_temporary(); - diff += "(ret_temp)$ := "; + call_fwd += "(ret_temp)$ := "; } // TODO: This is untested for functions with no return value. Requires handling of out and inout parameters in functions. if !object.empty() { // Prepend object call - diff += "(object)$."; + call_primal += "(object)$."; + call_fwd += "(object)$."; + call_rws += "(object)$."; } - diff += "(function_name)$(ctx*.fwd_suffix)$("; + call_primal += "(function_name)$("; + call_fwd += "(function_name)$(ctx*.fwd_suffix)$("; + call_rws += "(function_name)$(ctx*.rws_suffix)$("; if !object.empty() { // Add this_d argument. - diff += "(object_d)$, "; + call_fwd += "(object_d)$, "; + call_rws += "(object_b)$, "; } for args do (arg) { + // TODO: Add taylor reverse handling. + call_primal += "(arg.primal)$, "; + call_fwd += "(arg.primal)$, "; + call_rws += "(arg.primal)$, "; if arg.active { - diff += "(arg.primal)$, (arg.fwd)$, "; - } - else { - diff += "(arg.primal)$, "; + call_fwd += "(arg.fwd)$, "; + call_rws += "(arg.rws)$, "; } } - diff += ");\n"; if has_return { functions : std::vector = (); @@ -5018,9 +5028,28 @@ autodiff_expression_handler: type = { } ret_name_d : std::string = ret_name + ctx*.fwd_suffix; + ret_name_b : std::string = ret_name + ctx*.rws_suffix; + + call_rws += "_rb_, "; + + call_primal += ")"; + call_fwd += ");\n"; + call_rws += ");\n"; - primal_expr = "(ret_temp)$.(ret_name)$"; + diff.add_forward(call_fwd); + + primal_expr = call_primal; fwd_expr = "(ret_temp)$.(ret_name_d)$"; + rws_expr = "_ = (call_rws)$"; + } + else { + call_primal += ");\n"; + call_fwd += ");\n"; + call_rws += ");\n"; + + diff.add_forward(call_fwd); + diff.add_reverse_primal(call_primal); + diff.add_reverse_backprop(call_rws); } // TODO: Add function to list of functions/objects for differentiation for the no return case. From a05accd4fc177204adb9bc36085ad0492292d007 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 1 Sep 2025 15:23:47 +0200 Subject: [PATCH 49/54] Handling of statement parameters for loops in forward mode. --- regression-tests/pure2-autodiff.cpp2 | 13 +- .../test-results/pure2-autodiff.cpp | 204 ++-- .../test-results/pure2-autodiff.cpp2.output | 24 +- source/reflect.h | 984 ++++++++++-------- source/reflect.h2 | 58 +- 5 files changed, 714 insertions(+), 569 deletions(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index f1d789627..9394acfcf 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -114,7 +114,7 @@ ad_test: @autodiff @print type = { } intermediate_passive_var: (x: double, y: double) -> (r: double) = { - i: int = (); // TODO: Handle as passive when type information on call side is available. + i: int = (); r = x + y; i = 2; @@ -143,18 +143,19 @@ ad_test: @autodiff @print type = { } while_loop: (x: double, y: double) -> (r: double) = { - i: int = 0; - r = x; + + (copy i: int = 0, copy t: double = 0.0) while i < 2 next (i += 1) { - r = r + y ; + t = y; + r = r + t; } } do_while_loop: (x: double, y: double) -> (r: double) = { - i: int = 0; - r = x; + + (copy i: = 0) do { r = r + y ; } diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 67cfe16eb..14b64b179 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -18,10 +18,10 @@ class type_outer; #line 15 "pure2-autodiff.cpp2" class ad_test; -#line 194 "pure2-autodiff.cpp2" +#line 195 "pure2-autodiff.cpp2" class ad_test_reverse; -#line 260 "pure2-autodiff.cpp2" +#line 261 "pure2-autodiff.cpp2" } class ad_test_twice; @@ -205,22 +205,22 @@ using while_loop_ret = double; using do_while_loop_ret = double; -#line 154 "pure2-autodiff.cpp2" +#line 155 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret; using for_loop_ret = double; -#line 165 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret; using type_outer_use_ret = double; -#line 179 "pure2-autodiff.cpp2" +#line 180 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret; using type_outer_call_ret = double; -#line 186 "pure2-autodiff.cpp2" +#line 187 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret; struct add_1_d_ret { double r; double r_d; }; @@ -352,94 +352,94 @@ public: [[nodiscard]] static auto type_outer_call_d(cpp2::impl::in x, cp public: auto operator=(ad_test const&) -> void = delete; -#line 192 "pure2-autodiff.cpp2" +#line 193 "pure2-autodiff.cpp2" }; using func_outer_b_ret = double; [[nodiscard]] auto func_outer_b(cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& ret_b) -> func_outer_b_ret; -#line 194 "pure2-autodiff.cpp2" +#line 195 "pure2-autodiff.cpp2" class ad_test_reverse { using add_1_ret = double; -#line 196 "pure2-autodiff.cpp2" +#line 197 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret; using add_2_ret = double; -#line 200 "pure2-autodiff.cpp2" +#line 201 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret; using sub_1_ret = double; -#line 204 "pure2-autodiff.cpp2" +#line 205 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret; using sub_2_ret = double; -#line 208 "pure2-autodiff.cpp2" +#line 209 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret; using add_sub_2_ret = double; -#line 212 "pure2-autodiff.cpp2" +#line 213 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret; using mul_1_ret = double; -#line 216 "pure2-autodiff.cpp2" +#line 217 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret; using mul_2_ret = double; -#line 220 "pure2-autodiff.cpp2" +#line 221 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret; using div_1_ret = double; -#line 224 "pure2-autodiff.cpp2" +#line 225 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret; using div_2_ret = double; -#line 228 "pure2-autodiff.cpp2" +#line 229 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret; using mul_div_2_ret = double; -#line 232 "pure2-autodiff.cpp2" +#line 233 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret; using mul_add_ret = double; -#line 236 "pure2-autodiff.cpp2" +#line 237 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret; using add_mul_ret = double; -#line 240 "pure2-autodiff.cpp2" +#line 241 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret; using sin_call_ret = double; -#line 244 "pure2-autodiff.cpp2" +#line 245 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret; using func_ret = double; -#line 248 "pure2-autodiff.cpp2" +#line 249 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret; using func_call_ret = double; -#line 252 "pure2-autodiff.cpp2" +#line 253 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret; using func_outer_call_ret = double; -#line 256 "pure2-autodiff.cpp2" +#line 257 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret; using add_1_b_ret = double; @@ -495,14 +495,14 @@ public: [[nodiscard]] static auto func_outer_call_b(cpp2::impl::in x, do public: auto operator=(ad_test_reverse const&) -> void = delete; -#line 259 "pure2-autodiff.cpp2" +#line 260 "pure2-autodiff.cpp2" }; } class ad_test_twice { using mul_1_ret = double; -#line 263 "pure2-autodiff.cpp2" +#line 264 "pure2-autodiff.cpp2" public: [[nodiscard]] static auto mul_1(cpp2::impl::in x) -> mul_1_ret; struct mul_1_d_ret { double r; double r_d; }; @@ -522,15 +522,15 @@ public: [[nodiscard]] static auto mul_1_d_d2(cpp2::impl::in x, cpp2::imp public: auto operator=(ad_test_twice const&) -> void = delete; -#line 266 "pure2-autodiff.cpp2" +#line 267 "pure2-autodiff.cpp2" }; auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void; -#line 272 "pure2-autodiff.cpp2" +#line 273 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void; -#line 279 "pure2-autodiff.cpp2" +#line 280 "pure2-autodiff.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -732,7 +732,7 @@ return std::move(ret.value()); } [[nodiscard]] auto ad_test::intermediate_passive_var(cpp2::impl::in x, cpp2::impl::in y) -> intermediate_passive_var_ret{ cpp2::impl::deferred_init r; #line 117 "pure2-autodiff.cpp2" - int i {}; // TODO: Handle as passive when type information on call side is available. + int i {}; r.construct(x + y); i = 2; @@ -773,32 +773,48 @@ return std::move(ret.value()); } [[nodiscard]] auto ad_test::while_loop(cpp2::impl::in x, cpp2::impl::in y) -> while_loop_ret{ cpp2::impl::deferred_init r; #line 146 "pure2-autodiff.cpp2" - int i {0}; - r.construct(x); +{ +int i{0}; +double t{0.0}; + +#line 149 "pure2-autodiff.cpp2" for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - r.value() = r.value() + y; - }return std::move(r.value()); + t = y; + r.value() = r.value() + t; + } +} +#line 150 "pure2-autodiff.cpp2" + return std::move(r.value()); + +#line 153 "pure2-autodiff.cpp2" } -#line 154 "pure2-autodiff.cpp2" +#line 155 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::do_while_loop(cpp2::impl::in x, cpp2::impl::in y) -> do_while_loop_ret{ cpp2::impl::deferred_init r; -#line 155 "pure2-autodiff.cpp2" - int i {0}; - +#line 156 "pure2-autodiff.cpp2" r.construct(x); +{ +auto i{0}; + +#line 159 "pure2-autodiff.cpp2" do { r.value() = r.value() + y; } while ( [&]{ (i += 1) ; return true; }() && - cpp2::impl::cmp_less(i,2));return std::move(r.value()); + cpp2::impl::cmp_less(i,2)); +} +#line 160 "pure2-autodiff.cpp2" + return std::move(r.value()); + +#line 164 "pure2-autodiff.cpp2" } -#line 165 "pure2-autodiff.cpp2" +#line 166 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::for_loop(cpp2::impl::in x, cpp2::impl::in y) -> for_loop_ret{ cpp2::impl::deferred_init r; -#line 166 "pure2-autodiff.cpp2" +#line 167 "pure2-autodiff.cpp2" std::vector v {}; CPP2_UFCS(push_back)(v, x); @@ -812,20 +828,20 @@ return std::move(ret.value()); } }return std::move(r.value()); } -#line 179 "pure2-autodiff.cpp2" +#line 180 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::type_outer_use(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_use_ret{ cpp2::impl::deferred_init r; -#line 180 "pure2-autodiff.cpp2" +#line 181 "pure2-autodiff.cpp2" type_outer t {}; t.a = x; r.construct(cpp2::move(t).a + y); return std::move(r.value()); } -#line 186 "pure2-autodiff.cpp2" +#line 187 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test::type_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> type_outer_call_ret{ cpp2::impl::deferred_init r; -#line 187 "pure2-autodiff.cpp2" +#line 188 "pure2-autodiff.cpp2" type_outer t {}; t.a = x; @@ -1097,23 +1113,28 @@ cpp2::impl::deferred_init t_d; [[nodiscard]] auto ad_test::while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> while_loop_d_ret{ double r {0.0}; - double r_d {0.0}; -int i {0}; - r_d = x_d; + double r_d {0.0};r_d = x_d; r = x; +{ +int i{0}; +double t{0.0}; +double t_d{}; for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { - r_d = r_d + y_d; - r = r + y; + t_d = y_d; + t = y; + r_d = r_d + t_d; + r = r + t; } +} return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::do_while_loop_d(cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d) -> do_while_loop_d_ret{ double r {0.0}; - double r_d {0.0}; -int i {0}; - r_d = x_d; + double r_d {0.0};r_d = x_d; r = x; +{ +auto i{0}; do { r_d = r_d + y_d; r = r + y; @@ -1123,6 +1144,7 @@ int i {0}; ; return true; }() && cpp2::impl::cmp_less(i,2) ); +} return { std::move(r), std::move(r_d) }; } @@ -1193,115 +1215,115 @@ type_outer_d t_d {}; ret_b = 0.0; return ret; } -#line 196 "pure2-autodiff.cpp2" +#line 197 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::add_1(cpp2::impl::in x, cpp2::impl::in y) -> add_1_ret{ cpp2::impl::deferred_init r; -#line 197 "pure2-autodiff.cpp2" +#line 198 "pure2-autodiff.cpp2" r.construct(x + y); return std::move(r.value()); } -#line 200 "pure2-autodiff.cpp2" +#line 201 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::add_2(cpp2::impl::in x, cpp2::impl::in y) -> add_2_ret{ cpp2::impl::deferred_init r; -#line 201 "pure2-autodiff.cpp2" +#line 202 "pure2-autodiff.cpp2" r.construct(x + y + x); return std::move(r.value()); } -#line 204 "pure2-autodiff.cpp2" +#line 205 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::sub_1(cpp2::impl::in x, cpp2::impl::in y) -> sub_1_ret{ cpp2::impl::deferred_init r; -#line 205 "pure2-autodiff.cpp2" +#line 206 "pure2-autodiff.cpp2" r.construct(x - y); return std::move(r.value()); } -#line 208 "pure2-autodiff.cpp2" +#line 209 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::sub_2(cpp2::impl::in x, cpp2::impl::in y) -> sub_2_ret{ cpp2::impl::deferred_init r; -#line 209 "pure2-autodiff.cpp2" +#line 210 "pure2-autodiff.cpp2" r.construct(x - y - x); return std::move(r.value()); } -#line 212 "pure2-autodiff.cpp2" +#line 213 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::add_sub_2(cpp2::impl::in x, cpp2::impl::in y) -> add_sub_2_ret{ cpp2::impl::deferred_init r; -#line 213 "pure2-autodiff.cpp2" +#line 214 "pure2-autodiff.cpp2" r.construct(x + y - x); return std::move(r.value()); } -#line 216 "pure2-autodiff.cpp2" +#line 217 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::mul_1(cpp2::impl::in x, cpp2::impl::in y) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 217 "pure2-autodiff.cpp2" +#line 218 "pure2-autodiff.cpp2" r.construct(x * y); return std::move(r.value()); } -#line 220 "pure2-autodiff.cpp2" +#line 221 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::mul_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_2_ret{ cpp2::impl::deferred_init r; -#line 221 "pure2-autodiff.cpp2" +#line 222 "pure2-autodiff.cpp2" r.construct(x * y * x); return std::move(r.value()); } -#line 224 "pure2-autodiff.cpp2" +#line 225 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::div_1(cpp2::impl::in x, cpp2::impl::in y) -> div_1_ret{ cpp2::impl::deferred_init r; -#line 225 "pure2-autodiff.cpp2" +#line 226 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)); return std::move(r.value()); } -#line 228 "pure2-autodiff.cpp2" +#line 229 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::div_2(cpp2::impl::in x, cpp2::impl::in y) -> div_2_ret{ cpp2::impl::deferred_init r; -#line 229 "pure2-autodiff.cpp2" +#line 230 "pure2-autodiff.cpp2" r.construct(x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y) / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),y)); return std::move(r.value()); } -#line 232 "pure2-autodiff.cpp2" +#line 233 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::mul_div_2(cpp2::impl::in x, cpp2::impl::in y) -> mul_div_2_ret{ cpp2::impl::deferred_init r; -#line 233 "pure2-autodiff.cpp2" +#line 234 "pure2-autodiff.cpp2" r.construct(x * y / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(y),x)); return std::move(r.value()); } -#line 236 "pure2-autodiff.cpp2" +#line 237 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::mul_add(cpp2::impl::in x, cpp2::impl::in y) -> mul_add_ret{ cpp2::impl::deferred_init r; -#line 237 "pure2-autodiff.cpp2" +#line 238 "pure2-autodiff.cpp2" r.construct(x * (x + y)); return std::move(r.value()); } -#line 240 "pure2-autodiff.cpp2" +#line 241 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::add_mul(cpp2::impl::in x, cpp2::impl::in y) -> add_mul_ret{ cpp2::impl::deferred_init r; -#line 241 "pure2-autodiff.cpp2" +#line 242 "pure2-autodiff.cpp2" r.construct(x + x * y); return std::move(r.value()); } -#line 244 "pure2-autodiff.cpp2" +#line 245 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::sin_call(cpp2::impl::in x, cpp2::impl::in y) -> sin_call_ret{ cpp2::impl::deferred_init r; -#line 245 "pure2-autodiff.cpp2" +#line 246 "pure2-autodiff.cpp2" r.construct(sin(x - y)); return std::move(r.value()); } -#line 248 "pure2-autodiff.cpp2" +#line 249 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::func(cpp2::impl::in x, cpp2::impl::in y) -> func_ret{ cpp2::impl::deferred_init ret; -#line 249 "pure2-autodiff.cpp2" +#line 250 "pure2-autodiff.cpp2" ret.construct(x + y); return std::move(ret.value()); } -#line 252 "pure2-autodiff.cpp2" +#line 253 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::func_call(cpp2::impl::in x, cpp2::impl::in y) -> func_call_ret{ cpp2::impl::deferred_init r; -#line 253 "pure2-autodiff.cpp2" +#line 254 "pure2-autodiff.cpp2" r.construct(x * func(x, y)); return std::move(r.value()); } -#line 256 "pure2-autodiff.cpp2" +#line 257 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_reverse::func_outer_call(cpp2::impl::in x, cpp2::impl::in y) -> func_outer_call_ret{ cpp2::impl::deferred_init r; -#line 257 "pure2-autodiff.cpp2" +#line 258 "pure2-autodiff.cpp2" r.construct(x * func_outer(x, y)); return std::move(r.value()); } @@ -1473,13 +1495,13 @@ double temp_2_b {0.0}; temp_2_b = 0.0; return r; } -#line 260 "pure2-autodiff.cpp2" +#line 261 "pure2-autodiff.cpp2" } -#line 263 "pure2-autodiff.cpp2" +#line 264 "pure2-autodiff.cpp2" [[nodiscard]] auto ad_test_twice::mul_1(cpp2::impl::in x) -> mul_1_ret{ cpp2::impl::deferred_init r; -#line 264 "pure2-autodiff.cpp2" +#line 265 "pure2-autodiff.cpp2" r.construct(x * x); return std::move(r.value()); } @@ -1516,12 +1538,12 @@ double temp_1_d2 {x_d * x_d2 + x * x_d_d2}; return { std::move(r), std::move(r_d2), std::move(r_d), std::move(r_d_d2) }; } -#line 268 "pure2-autodiff.cpp2" +#line 269 "pure2-autodiff.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, cpp2::impl::in y, cpp2::impl::in y_d, auto const& ret) -> void{ std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", x_d = " + cpp2::to_string(x_d) + ", y = " + cpp2::to_string(y) + ", y_d = " + cpp2::to_string(y_d) + ") = (r = " + cpp2::to_string(ret.r) + ", r_d = " + cpp2::to_string(ret.r_d) + ")" << std::endl; } -#line 272 "pure2-autodiff.cpp2" +#line 273 "pure2-autodiff.cpp2" auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void{ r_b = 1.0; std::cout << "diff(" + cpp2::to_string(func) + ") at (x = " + cpp2::to_string(x) + ", y = " + cpp2::to_string(y) + ", r_b = " + cpp2::to_string(r_b) + ") = (r = " + cpp2::to_string(ret) + ", x_b = " + cpp2::to_string(x_b) + ", y_b = " + cpp2::to_string(y_b) + ")" << std::endl; @@ -1529,7 +1551,7 @@ auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in int{ double x {2.0}; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index c297b8b72..767174482 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -261,12 +261,16 @@ ad_test:/* @autodiff @print */ type = in y: double, ) -> (out r: double, ) = { - i: int = 0; r = x; + ( + copy i: int = 0, + copy t: double = 0.0, + ) while i < 2 next (i += 1) { - r = r + y; + t = y; + r = r + t; } return; } @@ -276,8 +280,8 @@ ad_test:/* @autodiff @print */ type = in y: double, ) -> (out r: double, ) = { - i: int = 0; r = x; + (copy i: _ = 0, ) do { r = r + y; @@ -781,14 +785,20 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i: int = 0; r_d = x_d; r = x; + ( + copy i: int = 0, + copy t: double = 0.0, + copy t_d: double = (), + ) while i < 2 next (i += 1) { - r_d = r_d + y_d; - r = r + y; + t_d = y_d; + t = y; + r_d = r_d + t_d; + r = r + t; } return; } @@ -803,9 +813,9 @@ ad_test:/* @autodiff @print */ type = out r_d: double = 0.0, ) = { - i: int = 0; r_d = x_d; r = x; + (copy i: _ = 0, ) do { r_d = r_d + y_d; diff --git a/source/reflect.h b/source/reflect.h index 5f59471dd..bedc15a21 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -140,80 +140,80 @@ class autodiff_expression_handler; #line 5380 "reflect.h2" class autodiff_stmt_handler; -#line 5675 "reflect.h2" +#line 5729 "reflect.h2" class autodiff_declaration_handler; -#line 6020 "reflect.h2" +#line 6074 "reflect.h2" class expression_flags; -#line 6036 "reflect.h2" +#line 6090 "reflect.h2" class regex_token; -#line 6063 "reflect.h2" +#line 6117 "reflect.h2" class regex_token_check; -#line 6084 "reflect.h2" +#line 6138 "reflect.h2" class regex_token_code; -#line 6105 "reflect.h2" +#line 6159 "reflect.h2" class regex_token_empty; -#line 6123 "reflect.h2" +#line 6177 "reflect.h2" class regex_token_list; -#line 6175 "reflect.h2" +#line 6229 "reflect.h2" class parse_context_group_state; -#line 6236 "reflect.h2" +#line 6290 "reflect.h2" class parse_context_branch_reset_state; -#line 6279 "reflect.h2" +#line 6333 "reflect.h2" class parse_context; -#line 6680 "reflect.h2" +#line 6734 "reflect.h2" class generation_function_context; -#line 6698 "reflect.h2" +#line 6752 "reflect.h2" class generation_context; -#line 6897 "reflect.h2" +#line 6951 "reflect.h2" class alternative_token; -#line 6912 "reflect.h2" +#line 6966 "reflect.h2" class alternative_token_gen; -#line 6977 "reflect.h2" +#line 7031 "reflect.h2" class any_token; -#line 6994 "reflect.h2" +#line 7048 "reflect.h2" class atomic_group_token; -#line 7024 "reflect.h2" +#line 7078 "reflect.h2" class char_token; -#line 7139 "reflect.h2" +#line 7193 "reflect.h2" class class_token; -#line 7363 "reflect.h2" +#line 7417 "reflect.h2" class group_ref_token; -#line 7500 "reflect.h2" +#line 7554 "reflect.h2" class group_token; -#line 7847 "reflect.h2" +#line 7901 "reflect.h2" class lookahead_lookbehind_token; -#line 7942 "reflect.h2" +#line 7996 "reflect.h2" class range_token; -#line 8099 "reflect.h2" +#line 8153 "reflect.h2" class special_range_token; -#line 8185 "reflect.h2" +#line 8239 "reflect.h2" template class regex_generator; -#line 8448 "reflect.h2" +#line 8502 "reflect.h2" } } @@ -2115,98 +2115,103 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba private: meta::function_declaration mf; + private: std::vector last_params {}; + public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5393 "reflect.h2" +#line 5395 "reflect.h2" + public: auto handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void; + +#line 5439 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5398 "reflect.h2" +#line 5444 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5403 "reflect.h2" +#line 5449 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5454 "reflect.h2" +#line 5500 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5459 "reflect.h2" +#line 5505 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5464 "reflect.h2" +#line 5510 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5469 "reflect.h2" +#line 5517 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5477 "reflect.h2" +#line 5524 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5494 "reflect.h2" +#line 5541 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5544 "reflect.h2" +#line 5598 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5555 "reflect.h2" +#line 5609 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5559 "reflect.h2" +#line 5613 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5584 "reflect.h2" +#line 5638 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5588 "reflect.h2" +#line 5642 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5592 "reflect.h2" +#line 5646 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5596 "reflect.h2" +#line 5650 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5600 "reflect.h2" +#line 5654 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5604 "reflect.h2" +#line 5658 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5608 "reflect.h2" +#line 5662 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5612 "reflect.h2" +#line 5666 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5616 "reflect.h2" +#line 5670 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5620 "reflect.h2" +#line 5674 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5624 "reflect.h2" +#line 5678 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5628 "reflect.h2" +#line 5682 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5632 "reflect.h2" +#line 5686 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5637 "reflect.h2" +#line 5691 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5669 "reflect.h2" +#line 5723 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5673 "reflect.h2" +#line 5727 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5679 "reflect.h2" +#line 5733 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2216,37 +2221,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5691 "reflect.h2" +#line 5745 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5696 "reflect.h2" +#line 5750 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5854 "reflect.h2" +#line 5908 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5882 "reflect.h2" +#line 5936 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5906 "reflect.h2" +#line 5960 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5911 "reflect.h2" +#line 5965 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5914 "reflect.h2" +#line 5968 "reflect.h2" }; -#line 5917 "reflect.h2" +#line 5971 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 6016 "reflect.h2" +#line 6070 "reflect.h2" using error_func = std::function x)>; -#line 6020 "reflect.h2" +#line 6074 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2281,20 +2286,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 6028 "reflect.h2" +#line 6082 "reflect.h2" }; -#line 6036 "reflect.h2" +#line 6090 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 6044 "reflect.h2" +#line 6098 "reflect.h2" public: explicit regex_token(); -#line 6049 "reflect.h2" +#line 6103 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2306,103 +2311,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 6055 "reflect.h2" +#line 6109 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 6061 "reflect.h2" +#line 6115 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 6067 "reflect.h2" +#line 6121 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 6074 "reflect.h2" +#line 6128 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6078 "reflect.h2" +#line 6132 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6079 "reflect.h2" +#line 6133 "reflect.h2" }; -#line 6082 "reflect.h2" +#line 6136 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6088 "reflect.h2" +#line 6142 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6095 "reflect.h2" +#line 6149 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6099 "reflect.h2" +#line 6153 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6100 "reflect.h2" +#line 6154 "reflect.h2" }; -#line 6103 "reflect.h2" +#line 6157 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6109 "reflect.h2" +#line 6163 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6113 "reflect.h2" +#line 6167 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6117 "reflect.h2" +#line 6171 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6118 "reflect.h2" +#line 6172 "reflect.h2" }; -#line 6121 "reflect.h2" +#line 6175 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6127 "reflect.h2" +#line 6181 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6134 "reflect.h2" +#line 6188 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6140 "reflect.h2" +#line 6194 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6146 "reflect.h2" +#line 6200 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6154 "reflect.h2" +#line 6208 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2410,10 +2415,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6166 "reflect.h2" +#line 6220 "reflect.h2" }; -#line 6169 "reflect.h2" +#line 6223 "reflect.h2" // // Parse and generation context. // @@ -2429,33 +2434,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6189 "reflect.h2" +#line 6243 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6196 "reflect.h2" +#line 6250 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6208 "reflect.h2" +#line 6262 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6213 "reflect.h2" +#line 6267 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6217 "reflect.h2" +#line 6271 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6231 "reflect.h2" +#line 6285 "reflect.h2" }; -#line 6234 "reflect.h2" +#line 6288 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2468,25 +2473,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6252 "reflect.h2" +#line 6306 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6258 "reflect.h2" +#line 6312 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6265 "reflect.h2" +#line 6319 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6272 "reflect.h2" +#line 6326 "reflect.h2" }; -#line 6275 "reflect.h2" +#line 6329 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2502,7 +2507,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6291 "reflect.h2" +#line 6345 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2510,64 +2515,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6302 "reflect.h2" +#line 6356 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6315 "reflect.h2" +#line 6369 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6323 "reflect.h2" +#line 6377 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6327 "reflect.h2" +#line 6381 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6331 "reflect.h2" +#line 6385 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6343 "reflect.h2" +#line 6397 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6350 "reflect.h2" +#line 6404 "reflect.h2" public: auto next_alternative() & -> void; -#line 6356 "reflect.h2" +#line 6410 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6362 "reflect.h2" +#line 6416 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6366 "reflect.h2" +#line 6420 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6377 "reflect.h2" +#line 6431 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6381 "reflect.h2" +#line 6435 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6387 "reflect.h2" +#line 6441 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6391 "reflect.h2" +#line 6445 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6398 "reflect.h2" +#line 6452 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6409 "reflect.h2" +#line 6463 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2575,51 +2580,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6453 "reflect.h2" +#line 6507 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6465 "reflect.h2" +#line 6519 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6478 "reflect.h2" +#line 6532 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6501 "reflect.h2" +#line 6555 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6518 "reflect.h2" +#line 6572 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6539 "reflect.h2" +#line 6593 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6549 "reflect.h2" +#line 6603 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6553 "reflect.h2" +#line 6607 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6609 "reflect.h2" +#line 6663 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6648 "reflect.h2" +#line 6702 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6663 "reflect.h2" +#line 6717 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2631,10 +2636,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6674 "reflect.h2" +#line 6728 "reflect.h2" }; -#line 6677 "reflect.h2" +#line 6731 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2644,16 +2649,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6691 "reflect.h2" +#line 6745 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6694 "reflect.h2" +#line 6748 "reflect.h2" }; -#line 6697 "reflect.h2" +#line 6751 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2673,68 +2678,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6719 "reflect.h2" +#line 6773 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6725 "reflect.h2" +#line 6779 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6734 "reflect.h2" +#line 6788 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6745 "reflect.h2" +#line 6799 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6752 "reflect.h2" +#line 6806 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6772 "reflect.h2" +#line 6826 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6782 "reflect.h2" +#line 6836 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6805 "reflect.h2" +#line 6859 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6813 "reflect.h2" +#line 6867 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6817 "reflect.h2" +#line 6871 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6823 "reflect.h2" +#line 6877 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6829 "reflect.h2" +#line 6883 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6839 "reflect.h2" +#line 6893 "reflect.h2" public: auto finish_context() & -> void; -#line 6847 "reflect.h2" +#line 6901 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6853 "reflect.h2" +#line 6907 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6857 "reflect.h2" +#line 6911 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6861 "reflect.h2" +#line 6915 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6885 "reflect.h2" +#line 6939 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2742,7 +2747,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6891 "reflect.h2" +#line 6945 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2762,27 +2767,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6910 "reflect.h2" +#line 6964 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6916 "reflect.h2" +#line 6970 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6923 "reflect.h2" +#line 6977 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6940 "reflect.h2" +#line 6994 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6947 "reflect.h2" +#line 7001 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 6960 "reflect.h2" +#line 7014 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2790,19 +2795,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 6972 "reflect.h2" +#line 7026 "reflect.h2" }; -#line 6975 "reflect.h2" +#line 7029 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 6981 "reflect.h2" +#line 7035 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 6985 "reflect.h2" +#line 7039 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2810,7 +2815,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 6990 "reflect.h2" +#line 7044 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2818,17 +2823,17 @@ class any_token class atomic_group_token : public regex_token { -#line 6998 "reflect.h2" +#line 7052 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7009 "reflect.h2" +#line 7063 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7017 "reflect.h2" +#line 7071 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2836,7 +2841,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 7020 "reflect.h2" +#line 7074 "reflect.h2" }; // Regex syntax: a @@ -2844,34 +2849,34 @@ class atomic_group_token class char_token : public regex_token { -#line 7028 "reflect.h2" +#line 7082 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7037 "reflect.h2" +#line 7091 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7043 "reflect.h2" +#line 7097 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7047 "reflect.h2" +#line 7101 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7070 "reflect.h2" +#line 7124 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7091 "reflect.h2" +#line 7145 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7109 "reflect.h2" +#line 7163 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7124 "reflect.h2" +#line 7178 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7130 "reflect.h2" +#line 7184 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2879,33 +2884,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7134 "reflect.h2" +#line 7188 "reflect.h2" }; -#line 7137 "reflect.h2" +#line 7191 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7143 "reflect.h2" +#line 7197 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7155 "reflect.h2" +#line 7209 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7281 "reflect.h2" +#line 7335 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7290 "reflect.h2" +#line 7344 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7295 "reflect.h2" +#line 7349 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2913,20 +2918,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7302 "reflect.h2" +#line 7356 "reflect.h2" }; -#line 7305 "reflect.h2" +#line 7359 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7346 "reflect.h2" +#line 7400 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7357 "reflect.h2" +#line 7411 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2936,20 +2941,20 @@ class class_token class group_ref_token : public regex_token { -#line 7367 "reflect.h2" +#line 7421 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7379 "reflect.h2" +#line 7433 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7480 "reflect.h2" +#line 7534 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7484 "reflect.h2" +#line 7538 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2957,10 +2962,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7487 "reflect.h2" +#line 7541 "reflect.h2" }; -#line 7490 "reflect.h2" +#line 7544 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2974,29 +2979,29 @@ class group_ref_token class group_token : public regex_token { -#line 7504 "reflect.h2" +#line 7558 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7526 "reflect.h2" +#line 7580 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7540 "reflect.h2" +#line 7594 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7699 "reflect.h2" +#line 7753 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7707 "reflect.h2" +#line 7761 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7725 "reflect.h2" +#line 7779 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7756 "reflect.h2" +#line 7810 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -3005,25 +3010,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7763 "reflect.h2" +#line 7817 "reflect.h2" }; -#line 7766 "reflect.h2" +#line 7820 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7807 "reflect.h2" +#line 7861 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7827 "reflect.h2" +#line 7881 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7843 "reflect.h2" +#line 7897 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3031,20 +3036,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7851 "reflect.h2" +#line 7905 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7860 "reflect.h2" +#line 7914 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7871 "reflect.h2" +#line 7925 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7878 "reflect.h2" +#line 7932 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3052,26 +3057,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7881 "reflect.h2" +#line 7935 "reflect.h2" }; -#line 7884 "reflect.h2" +#line 7938 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7912 "reflect.h2" +#line 7966 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7940 "reflect.h2" +#line 7994 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 7946 "reflect.h2" +#line 8000 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3081,22 +3086,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 8026 "reflect.h2" +#line 8080 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 8038 "reflect.h2" +#line 8092 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 8051 "reflect.h2" +#line 8105 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 8070 "reflect.h2" +#line 8124 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8080 "reflect.h2" +#line 8134 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8091 "reflect.h2" +#line 8145 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3104,16 +3109,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8094 "reflect.h2" +#line 8148 "reflect.h2" }; -#line 8097 "reflect.h2" +#line 8151 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8103 "reflect.h2" +#line 8157 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3122,7 +3127,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8133 "reflect.h2" +#line 8187 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3131,14 +3136,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8155 "reflect.h2" +#line 8209 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8177 "reflect.h2" +#line 8231 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3159,24 +3164,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8200 "reflect.h2" +#line 8254 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8235 "reflect.h2" +#line 8289 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8249 "reflect.h2" +#line 8303 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8261 "reflect.h2" +#line 8315 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8316 "reflect.h2" +#line 8370 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3187,7 +3192,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8448 "reflect.h2" +#line 8502 "reflect.h2" } } @@ -9326,26 +9331,71 @@ auto i{0}; }}}} } -#line 5388 "reflect.h2" +#line 5390 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5391 "reflect.h2" +#line 5393 "reflect.h2" } -#line 5393 "reflect.h2" +#line 5395 "reflect.h2" + auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void{ + if (CPP2_UFCS(empty)(params)) { + return ; + } + + std::string fwd {"("}; + for ( auto const& param : params ) { + std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; + std::string type {CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))}; + + auto fwd_pass_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; + + autodiff_activity_check ada {ctx}; + CPP2_UFCS(pre_traverse)(ada, param); + + std::string init {""}; + std::string init_d {""}; + + if (CPP2_UFCS(has_initializer)(CPP2_UFCS(get_declaration)(param))) { + autodiff_expression_handler ad {ctx}; + CPP2_UFCS(pre_traverse)(ad, CPP2_UFCS(get_initializer)(CPP2_UFCS(get_declaration)(param))); + init = " = " + cpp2::to_string(ad.primal_expr) + ""; + + if (ada.active) { + init_d = " = " + cpp2::to_string(cpp2::move(ad).fwd_expr) + ""; + } + } + +#line 5424 "reflect.h2" + fwd += "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "; + if (ada.active) { + fwd += "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + cpp2::to_string(cpp2::move(init_d)) + ", "; + } + + CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type), cpp2::move(ada).active); + } + + if (!(leave_open)) { + fwd += ")"; + } + + diff += cpp2::move(fwd); + } + +#line 5439 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5398 "reflect.h2" +#line 5444 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5403 "reflect.h2" +#line 5449 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9396,30 +9446,31 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5454 "reflect.h2" +#line 5500 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5459 "reflect.h2" +#line 5505 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5464 "reflect.h2" +#line 5510 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + // TODO: Remove this hack when statements like compound_statement can access their root statement. + last_params = CPP2_UFCS(get_parameters)(stmt); base::traverse(stmt); } -#line 5469 "reflect.h2" +#line 5517 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - // Brackets are handled by the diff += "{\n"; base::traverse(stmt); diff += "}\n"; } -#line 5477 "reflect.h2" +#line 5524 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9436,8 +9487,12 @@ auto i{0}; } } -#line 5494 "reflect.h2" +#line 5541 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ + if (!(CPP2_UFCS(empty)(last_params))) { + handle_stmt_parameters(last_params, CPP2_UFCS(is_for)(stmt)); + } + if (CPP2_UFCS(is_while)(stmt)) { // TODO: Assumption is here that nothing is in the condition diff += "while " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_do_while_condition)(stmt))) + " "; @@ -9469,7 +9524,10 @@ auto i{0}; auto param {CPP2_UFCS(get_for_parameter)(stmt)}; auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; - diff += "(copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"; + if (CPP2_UFCS(empty)(last_params)) { + diff += "("; // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + } + diff += "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"; diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; if (CPP2_UFCS(has_next)(stmt)) { // TODO: Assumption is here that nothing is in the next expression @@ -9486,7 +9544,7 @@ auto i{0}; }} } -#line 5544 "reflect.h2" +#line 5598 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9498,12 +9556,12 @@ auto i{0}; } } -#line 5555 "reflect.h2" +#line 5609 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5559 "reflect.h2" +#line 5613 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9529,73 +9587,73 @@ auto i{0}; } } -#line 5584 "reflect.h2" +#line 5638 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5588 "reflect.h2" +#line 5642 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5592 "reflect.h2" +#line 5646 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5596 "reflect.h2" +#line 5650 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5600 "reflect.h2" +#line 5654 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5604 "reflect.h2" +#line 5658 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5608 "reflect.h2" +#line 5662 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5612 "reflect.h2" +#line 5666 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5616 "reflect.h2" +#line 5670 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5620 "reflect.h2" +#line 5674 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5624 "reflect.h2" +#line 5678 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5628 "reflect.h2" +#line 5682 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5632 "reflect.h2" +#line 5686 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5637 "reflect.h2" +#line 5691 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9604,7 +9662,7 @@ auto i{0}; { auto i{0}; -#line 5644 "reflect.h2" +#line 5698 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9619,7 +9677,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5657 "reflect.h2" +#line 5711 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9632,27 +9690,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5669 "reflect.h2" +#line 5723 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5686 "reflect.h2" +#line 5740 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5689 "reflect.h2" +#line 5743 "reflect.h2" } -#line 5691 "reflect.h2" +#line 5745 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5696 "reflect.h2" +#line 5750 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9782,10 +9840,10 @@ auto i{0}; return ; } -#line 5826 "reflect.h2" +#line 5880 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5829 "reflect.h2" +#line 5883 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9810,7 +9868,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5854 "reflect.h2" +#line 5908 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9838,7 +9896,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5882 "reflect.h2" +#line 5936 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9862,17 +9920,17 @@ auto i{0}; } } -#line 5906 "reflect.h2" +#line 5960 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5911 "reflect.h2" +#line 5965 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5917 "reflect.h2" +#line 5971 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -10048,7 +10106,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 6002 "reflect.h2" +#line 6056 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -10064,11 +10122,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 6018 "reflect.h2" +#line 6072 "reflect.h2" // Possible modifiers for a regular expression. // -#line 6022 "reflect.h2" +#line 6076 "reflect.h2" // mod: i // mod: m // mod: s @@ -10076,116 +10134,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 6031 "reflect.h2" +#line 6085 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 6040 "reflect.h2" +#line 6094 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 6042 "reflect.h2" +#line 6096 "reflect.h2" } -#line 6044 "reflect.h2" +#line 6098 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 6046 "reflect.h2" +#line 6100 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 6052 "reflect.h2" +#line 6106 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 6053 "reflect.h2" +#line 6107 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 6054 "reflect.h2" +#line 6108 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 6069 "reflect.h2" +#line 6123 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 6072 "reflect.h2" +#line 6126 "reflect.h2" } -#line 6074 "reflect.h2" +#line 6128 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 6078 "reflect.h2" +#line 6132 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6090 "reflect.h2" +#line 6144 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6093 "reflect.h2" +#line 6147 "reflect.h2" } -#line 6095 "reflect.h2" +#line 6149 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6099 "reflect.h2" +#line 6153 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6109 "reflect.h2" +#line 6163 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6111 "reflect.h2" +#line 6165 "reflect.h2" } -#line 6113 "reflect.h2" +#line 6167 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6117 "reflect.h2" +#line 6171 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6129 "reflect.h2" +#line 6183 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6132 "reflect.h2" +#line 6186 "reflect.h2" } -#line 6134 "reflect.h2" +#line 6188 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6140 "reflect.h2" +#line 6194 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6146 "reflect.h2" +#line 6200 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10194,7 +10252,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6154 "reflect.h2" +#line 6208 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10210,7 +10268,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6182 "reflect.h2" +#line 6236 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10218,14 +10276,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6190 "reflect.h2" +#line 6244 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6197 "reflect.h2" +#line 6251 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10237,15 +10295,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6209 "reflect.h2" +#line 6263 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6214 "reflect.h2" +#line 6268 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6218 "reflect.h2" +#line 6272 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10266,7 +10324,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6244 "reflect.h2" +#line 6298 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10275,20 +10333,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6253 "reflect.h2" +#line 6307 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6259 "reflect.h2" +#line 6313 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6266 "reflect.h2" +#line 6320 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10303,16 +10361,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6296 "reflect.h2" +#line 6350 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6300 "reflect.h2" +#line 6354 "reflect.h2" } -#line 6306 "reflect.h2" +#line 6360 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10322,7 +10380,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6316 "reflect.h2" +#line 6370 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10330,17 +10388,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6323 "reflect.h2" +#line 6377 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6327 "reflect.h2" +#line 6381 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6334 "reflect.h2" +#line 6388 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10350,7 +10408,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6343 "reflect.h2" +#line 6397 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10358,24 +10416,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6350 "reflect.h2" +#line 6404 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6358 "reflect.h2" +#line 6412 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6362 "reflect.h2" +#line 6416 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6366 "reflect.h2" +#line 6420 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10387,22 +10445,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6377 "reflect.h2" +#line 6431 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6383 "reflect.h2" +#line 6437 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6387 "reflect.h2" +#line 6441 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6391 "reflect.h2" +#line 6445 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10410,7 +10468,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6398 "reflect.h2" +#line 6452 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10422,10 +10480,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6411 "reflect.h2" +#line 6465 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6414 "reflect.h2" +#line 6468 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10465,7 +10523,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6454 "reflect.h2" +#line 6508 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10477,14 +10535,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6465 "reflect.h2" +#line 6519 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6466 "reflect.h2" +#line 6520 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6467 "reflect.h2" +#line 6521 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6469 "reflect.h2" +#line 6523 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10494,10 +10552,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6478 "reflect.h2" +#line 6532 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6480 "reflect.h2" +#line 6534 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10519,14 +10577,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6501 "reflect.h2" +#line 6555 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6502 "reflect.h2" +#line 6556 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6503 "reflect.h2" +#line 6557 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6505 "reflect.h2" +#line 6559 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10540,7 +10598,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6518 "reflect.h2" +#line 6572 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10562,7 +10620,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6539 "reflect.h2" +#line 6593 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10573,12 +10631,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6549 "reflect.h2" +#line 6603 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6550 "reflect.h2" +#line 6604 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6555 "reflect.h2" +#line 6609 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10633,7 +10691,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6609 "reflect.h2" +#line 6663 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10673,7 +10731,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6648 "reflect.h2" +#line 6702 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10689,21 +10747,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6665 "reflect.h2" +#line 6719 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6666 "reflect.h2" +#line 6720 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6667 "reflect.h2" +#line 6721 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6669 "reflect.h2" +#line 6723 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6684 "reflect.h2" +#line 6738 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10711,7 +10769,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6691 "reflect.h2" +#line 6745 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10721,22 +10779,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6709 "reflect.h2" +#line 6763 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6714 "reflect.h2" +#line 6768 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6720 "reflect.h2" +#line 6774 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6726 "reflect.h2" +#line 6780 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10745,7 +10803,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6734 "reflect.h2" +#line 6788 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10757,7 +10815,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6745 "reflect.h2" +#line 6799 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10765,7 +10823,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6752 "reflect.h2" +#line 6806 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10786,7 +10844,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6773 "reflect.h2" +#line 6827 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10796,7 +10854,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6783 "reflect.h2" +#line 6837 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10819,33 +10877,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6807 "reflect.h2" +#line 6861 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6813 "reflect.h2" +#line 6867 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6817 "reflect.h2" +#line 6871 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6823 "reflect.h2" +#line 6877 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6831 "reflect.h2" +#line 6885 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10854,7 +10912,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6839 "reflect.h2" +#line 6893 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10863,22 +10921,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6849 "reflect.h2" +#line 6903 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6853 "reflect.h2" +#line 6907 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6857 "reflect.h2" +#line 6911 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6861 "reflect.h2" +#line 6915 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10902,18 +10960,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6886 "reflect.h2" +#line 6940 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6901 "reflect.h2" +#line 6955 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6903 "reflect.h2" +#line 6957 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10924,15 +10982,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6918 "reflect.h2" +#line 6972 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6921 "reflect.h2" +#line 6975 "reflect.h2" } -#line 6923 "reflect.h2" +#line 6977 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -10950,7 +11008,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6940 "reflect.h2" +#line 6994 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -10958,7 +11016,7 @@ generation_function_context::generation_function_context(){} } } -#line 6947 "reflect.h2" +#line 7001 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -10972,7 +11030,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 6960 "reflect.h2" +#line 7014 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -10988,14 +11046,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 6981 "reflect.h2" +#line 7035 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 6983 "reflect.h2" +#line 7037 "reflect.h2" } -#line 6985 "reflect.h2" +#line 7039 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -11004,11 +11062,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 7000 "reflect.h2" +#line 7054 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 7002 "reflect.h2" +#line 7056 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -11016,7 +11074,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7009 "reflect.h2" +#line 7063 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11025,37 +11083,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7017 "reflect.h2" +#line 7071 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 7031 "reflect.h2" +#line 7085 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7035 "reflect.h2" +#line 7089 "reflect.h2" } -#line 7037 "reflect.h2" +#line 7091 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7041 "reflect.h2" +#line 7095 "reflect.h2" } -#line 7043 "reflect.h2" +#line 7097 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 7047 "reflect.h2" +#line 7101 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -11064,14 +11122,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 7053 "reflect.h2" +#line 7107 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 7058 "reflect.h2" +#line 7112 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -11084,7 +11142,7 @@ size_t i{0}; } } -#line 7070 "reflect.h2" +#line 7124 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11106,7 +11164,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7091 "reflect.h2" +#line 7145 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11125,7 +11183,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7109 "reflect.h2" +#line 7163 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11141,14 +11199,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7124 "reflect.h2" +#line 7178 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7130 "reflect.h2" +#line 7184 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11156,19 +11214,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7147 "reflect.h2" +#line 7201 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7148 "reflect.h2" +#line 7202 "reflect.h2" { -#line 7153 "reflect.h2" +#line 7207 "reflect.h2" } -#line 7156 "reflect.h2" +#line 7210 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11294,7 +11352,7 @@ size_t i{0}; ); } -#line 7281 "reflect.h2" +#line 7335 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11304,13 +11362,13 @@ size_t i{0}; ); } -#line 7290 "reflect.h2" +#line 7344 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7295 "reflect.h2" +#line 7349 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11321,12 +11379,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7307 "reflect.h2" +#line 7361 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7312 "reflect.h2" +#line 7366 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11360,7 +11418,7 @@ size_t i{0}; } -#line 7348 "reflect.h2" +#line 7402 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11369,19 +11427,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7371 "reflect.h2" +#line 7425 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7372 "reflect.h2" +#line 7426 "reflect.h2" { -#line 7377 "reflect.h2" +#line 7431 "reflect.h2" } -#line 7379 "reflect.h2" +#line 7433 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11483,19 +11541,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7480 "reflect.h2" +#line 7534 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7484 "reflect.h2" +#line 7538 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7508 "reflect.h2" +#line 7562 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11514,7 +11572,7 @@ size_t i{0}; return r; } -#line 7526 "reflect.h2" +#line 7580 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11529,7 +11587,7 @@ size_t i{0}; return r; } -#line 7540 "reflect.h2" +#line 7594 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11689,7 +11747,7 @@ size_t i{0}; } } -#line 7699 "reflect.h2" +#line 7753 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11698,7 +11756,7 @@ size_t i{0}; return r; } -#line 7707 "reflect.h2" +#line 7761 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11717,7 +11775,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7725 "reflect.h2" +#line 7779 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11749,7 +11807,7 @@ size_t i{0}; } } -#line 7756 "reflect.h2" +#line 7810 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11760,7 +11818,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7768 "reflect.h2" +#line 7822 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11799,7 +11857,7 @@ size_t i{0}; return r; } -#line 7809 "reflect.h2" +#line 7863 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11817,7 +11875,7 @@ size_t i{0}; }} } -#line 7829 "reflect.h2" +#line 7883 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11831,16 +11889,16 @@ size_t i{0}; } } -#line 7855 "reflect.h2" +#line 7909 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7858 "reflect.h2" +#line 7912 "reflect.h2" } -#line 7860 "reflect.h2" +#line 7914 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11852,7 +11910,7 @@ size_t i{0}; } } -#line 7871 "reflect.h2" +#line 7925 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11860,14 +11918,14 @@ size_t i{0}; return r; } -#line 7878 "reflect.h2" +#line 7932 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7886 "reflect.h2" +#line 7940 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11893,7 +11951,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7914 "reflect.h2" +#line 7968 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11919,11 +11977,11 @@ size_t i{0}; return r; } -#line 7951 "reflect.h2" +#line 8005 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 7953 "reflect.h2" +#line 8007 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -11997,7 +12055,7 @@ size_t i{0}; return nullptr; } -#line 8026 "reflect.h2" +#line 8080 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -12010,7 +12068,7 @@ size_t i{0}; }} } -#line 8038 "reflect.h2" +#line 8092 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -12024,7 +12082,7 @@ size_t i{0}; }} } -#line 8051 "reflect.h2" +#line 8105 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -12044,7 +12102,7 @@ size_t i{0}; return r; } -#line 8070 "reflect.h2" +#line 8124 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -12055,7 +12113,7 @@ size_t i{0}; return r; } -#line 8080 "reflect.h2" +#line 8134 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -12067,14 +12125,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8091 "reflect.h2" +#line 8145 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8103 "reflect.h2" +#line 8157 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12098,7 +12156,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8127 "reflect.h2" +#line 8181 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12108,7 +12166,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8139 "reflect.h2" +#line 8193 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12124,7 +12182,7 @@ size_t i{0}; } } -#line 8159 "reflect.h2" +#line 8213 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12142,15 +12200,15 @@ size_t i{0}; }} } -#line 8195 "reflect.h2" +#line 8249 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8198 "reflect.h2" +#line 8252 "reflect.h2" } -#line 8200 "reflect.h2" +#line 8254 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12186,7 +12244,7 @@ size_t i{0}; return source; } -#line 8235 "reflect.h2" +#line 8289 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12202,7 +12260,7 @@ size_t i{0}; } } -#line 8251 "reflect.h2" +#line 8305 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12211,7 +12269,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12266,7 +12324,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8320 "reflect.h2" +#line 8374 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12394,7 +12452,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8448 "reflect.h2" +#line 8502 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 2b026b1ac..8ea97b9f0 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -5385,11 +5385,57 @@ autodiff_stmt_handler: type = { mf: meta::function_declaration; + last_params: std::vector = (); + operator=: (out this, ctx_: *autodiff_context, mf_: meta::function_declaration) = { autodiff_handler_base = (ctx_); mf = mf_; } + handle_stmt_parameters: (inout this, params: std::vector, leave_open: bool) = { + if params.empty() { + return; + } + + fwd: std::string = "("; + for params do (param) { + name: std::string = param.get_declaration().name(); + type: std::string = param.get_declaration().type(); + + fwd_pass_style := to_string_view(param.get_passing_style()); + + ada: autodiff_activity_check = (ctx); + ada.pre_traverse(param); + + init : std::string = ""; + init_d: std::string = ""; + + if param.get_declaration().has_initializer() { + ad: autodiff_expression_handler = (ctx); + ad.pre_traverse(param.get_declaration().get_initializer()); + init = " = (ad.primal_expr)$"; + + if ada.active { + init_d = " = (ad.fwd_expr)$"; + } + } + + + fwd += "(fwd_pass_style)$ (name)$ : (type)$(init)$, "; + if ada.active { + fwd += "(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$(init_d)$, "; + } + + ctx*.add_variable_declaration(name, type, ada.active); + } + + if !leave_open { + fwd += ")"; + } + + diff += fwd; + } + traverse: (override inout this, decl: meta::declaration) = { base::traverse(decl); } @@ -5462,12 +5508,13 @@ autodiff_stmt_handler: type = { traverse: (override inout this, stmt: meta::statement) = { + // TODO: Remove this hack when statements like compound_statement can access their root statement. + last_params = stmt.get_parameters(); base::traverse(stmt); } traverse: (override inout this, stmt: meta::compound_statement) = { - // Brackets are handled by the diff += "{\n"; base::traverse(stmt); diff += "}\n"; @@ -5492,6 +5539,10 @@ autodiff_stmt_handler: type = { traverse: (override inout this, stmt: meta::iteration_statement) = { + if !last_params.empty() { + handle_stmt_parameters(last_params, stmt.is_for()); + } + if stmt.is_while() { // TODO: Assumption is here that nothing is in the condition diff += "while (stmt.get_do_while_condition().to_string())$ "; @@ -5523,7 +5574,10 @@ autodiff_stmt_handler: type = { param := stmt.get_for_parameter(); param_style := to_string_view(param.get_passing_style()); param_decl := param.get_declaration(); - diff += "(copy (param_decl.name())$_d_iter := (range)$(ctx*.fwd_suffix)$.begin())\n"; + if last_params.empty() { + diff += "("; // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + } + diff += "copy (param_decl.name())$_d_iter := (range)$(ctx*.fwd_suffix)$.begin())\n"; diff += "for (range)$ next ("; if stmt.has_next() { // TODO: Assumption is here that nothing is in the next expression From c8fdb0632b96c7c59fba4f496fa0694e023e63fe Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Tue, 2 Sep 2025 16:34:24 +0200 Subject: [PATCH 50/54] Reverse handling of for loops. --- source/reflect.h2 | 182 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 154 insertions(+), 28 deletions(-) diff --git a/source/reflect.h2 b/source/reflect.h2 index 8ea97b9f0..50080edc0 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -4592,6 +4592,7 @@ autodiff_diff_code: type = { operator=:(out this, ctx_: *autodiff_context) = { ctx = ctx_; } + operator=:(out this, that) = {} add_forward : (inout this, v: std::string) = { if ctx*.is_forward() { fwd += v; }} add_reverse_primal : (inout this, v: std::string) = { if ctx*.is_reverse() { rws_primal += v; }} @@ -4777,6 +4778,7 @@ autodiff_expression_handler: type = { return r; } + prepare_backprop: (this, rhs_b: std::string, lhs: std::string) -> std::string = prepare_backprop(rhs_b, lhs, lhs + ctx*.fwd_suffix, lhs + ctx*.rws_suffix); gen_assignment: (inout this, lhs: std::string, lhs_d: std::string, lhs_b: std::string, rhs: std::string, rhs_d: std::string, rhs_b: std::string) = { diff.add_forward("(lhs_d)$ = (rhs_d)$;\n"); @@ -5386,18 +5388,21 @@ autodiff_stmt_handler: type = { mf: meta::function_declaration; last_params: std::vector = (); + overwritten: std::vector = (); + + overwrite_push_pop: bool = false; operator=: (out this, ctx_: *autodiff_context, mf_: meta::function_declaration) = { autodiff_handler_base = (ctx_); mf = mf_; } - handle_stmt_parameters: (inout this, params: std::vector, leave_open: bool) = { + handle_stmt_parameters: (inout this, params: std::vector) -> autodiff_diff_code = { + r : autodiff_diff_code = (ctx); if params.empty() { - return; + return r; } - fwd: std::string = "("; for params do (param) { name: std::string = param.get_declaration().name(); type: std::string = param.get_declaration().type(); @@ -5409,6 +5414,7 @@ autodiff_stmt_handler: type = { init : std::string = ""; init_d: std::string = ""; + // TODO: Add handling for reverse expressions if param.get_declaration().has_initializer() { ad: autodiff_expression_handler = (ctx); @@ -5421,19 +5427,16 @@ autodiff_stmt_handler: type = { } - fwd += "(fwd_pass_style)$ (name)$ : (type)$(init)$, "; + r.add_forward("(fwd_pass_style)$ (name)$ : (type)$(init)$, "); + r.add_reverse_primal("(fwd_pass_style)$ (name)$ : (type)$(init)$, "); if ada.active { - fwd += "(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$(init_d)$, "; + r.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$(init_d)$, "); } ctx*.add_variable_declaration(name, type, ada.active); } - if !leave_open { - fwd += ")"; - } - - diff += fwd; + return r; } traverse: (override inout this, decl: meta::declaration) = { @@ -5465,9 +5468,11 @@ autodiff_stmt_handler: type = { if active { fwd_ad_type : = ctx*.get_fwd_ad_type(type); + rws_ad_type : = ctx*.get_rws_ad_type(type); prim_init: std::string = ""; fwd_init : std::string = ""; + rws_init : std::string = ""; if o.has_initializer() { ad: autodiff_expression_handler = (ctx); @@ -5476,14 +5481,23 @@ autodiff_stmt_handler: type = { prim_init = " = " + ad.primal_expr; fwd_init = " = " + ad.fwd_expr; + rws_init = " = ()"; // TODO: Proper initialization. + + if ad.rws_expr != "()" { + diff.add_reverse_backprop(ad.prepare_backprop(ad.rws_expr, lhs)); + } if type == "_" && ad.fwd_expr == "()" { // Special handling for auto initialization from a literal. fwd_init = " = " + ctx*.get_fwd_ad_type("double") + "()"; } } - diff += "(lhs)$(ctx*.fwd_suffix)$ : (fwd_ad_type)$(fwd_init)$;\n"; - diff += "(lhs)$ : (type)$(prim_init)$;\n"; + + diff.add_forward("(lhs)$(ctx*.fwd_suffix)$ : (fwd_ad_type)$(fwd_init)$;\n"); + diff.add_forward("(lhs)$ : (type)$(prim_init)$;\n"); + + diff.add_reverse_primal("(lhs)$(ctx*.rws_suffix)$ : (rws_ad_type)$(rws_init)$;\n"); + diff.add_reverse_primal("(lhs)$ : (type)$(prim_init)$;\n"); } else { diff += "(lhs)$: (type)$"; @@ -5515,9 +5529,37 @@ autodiff_stmt_handler: type = { traverse: (override inout this, stmt: meta::compound_statement) = { - diff += "{\n"; - base::traverse(stmt); - diff += "}\n"; + ad : autodiff_stmt_handler = (ctx, mf); + ad_push_pop: autodiff_stmt_handler = (ctx, mf); + ad_push_pop.overwrite_push_pop = true; + + diff.add_forward("{\n"); + diff.add_reverse_primal("{\n"); + diff.add_reverse_backprop("}\n"); + + for stmt.get_statements() do (cur) { + ad.pre_traverse(cur); + ad_push_pop.pre_traverse(cur); + } + + for ad.overwritten do (cur) { + r := ctx*.lookup_variable_declaration(cur); + diff.add_reverse_primal("cpp2::ad_stack::push<(r.decl)$>((cur)$);"); + } + + diff.add_forward(ad.diff.fwd); + diff.add_reverse_primal(ad.diff.rws_primal); + diff.add_reverse_backprop(ad_push_pop.diff.rws_backprop); + diff.add_reverse_backprop(ad_push_pop.diff.rws_primal); + + for ad.overwritten do (cur) { + r := ctx*.lookup_variable_declaration(cur); + diff.add_reverse_backprop("(cur)$ = cpp2::ad_stack::pop<(r.decl)$>();"); + } + + diff.add_forward("}\n"); + diff.add_reverse_primal("}\n"); + diff.add_reverse_backprop("{\n"); } @@ -5537,13 +5579,32 @@ autodiff_stmt_handler: type = { } } + reverse_next: (this, expr: std::string) -> std::string = { + if expr.contains("+=") { + return string_util::replace_all(expr, "+=", "-="); + } + else if expr.contains("-=") { + return string_util::replace_all(expr, "-=", "+="); + } + + mf.error("AD: Do not know how to reverse: (expr)$"); + + return "Error"; + + } + traverse: (override inout this, stmt: meta::iteration_statement) = { - if !last_params.empty() { - handle_stmt_parameters(last_params, stmt.is_for()); + diff_params := handle_stmt_parameters(last_params); + + if ctx*.is_reverse() && (stmt.is_while() || stmt.is_do()) { + stmt.error("AD: Alpha limitiation now reverse mode for while or do while."); } if stmt.is_while() { + if !last_params.empty() { + diff.add_forward("(" + diff_params.fwd + ")"); + } // TODO: Assumption is here that nothing is in the condition diff += "while (stmt.get_do_while_condition().to_string())$ "; if stmt.has_next() { @@ -5554,6 +5615,10 @@ autodiff_stmt_handler: type = { pre_traverse(stmt.get_do_while_body()); } else if stmt.is_do() { + if !last_params.empty() { + diff.add_forward("(" + diff_params.fwd + ")"); + } + // TODO: Assumption is here that nothing is in the condition diff += "do "; pre_traverse(stmt.get_do_while_body()); @@ -5574,23 +5639,55 @@ autodiff_stmt_handler: type = { param := stmt.get_for_parameter(); param_style := to_string_view(param.get_passing_style()); param_decl := param.get_declaration(); - if last_params.empty() { - diff += "("; // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + + rws : std::string = "("; + rws_restore: std::string = ""; + diff.add_forward("("); // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + diff.add_reverse_primal("{\n"); + if !last_params.empty() { + for last_params do (cur) { + if cur.get_declaration().has_initializer() { + // TODO: Handle no type and no initializer. Handle passing style. + diff.add_reverse_primal("(cur.get_declaration().name())$: (cur.get_declaration().type())$ = (cur.get_declaration().get_initializer().to_string())$;\n"); + rws_restore += "cpp2::ad_stack::push<(cur.get_declaration().type())$>((cur.get_declaration().name())$);\n"; + rws += "(to_string_view(cur.get_passing_style()))$ (cur.get_declaration().name())$: (cur.get_declaration().type())$ = cpp2::ad_stack::pop<(cur.get_declaration().type())$>(), "; + } + } + diff.add_forward(diff_params.fwd); } - diff += "copy (param_decl.name())$_d_iter := (range)$(ctx*.fwd_suffix)$.begin())\n"; - diff += "for (range)$ next ("; + diff.add_forward("copy (param_decl.name())$(ctx*.fwd_suffix)$_iter := (range)$(ctx*.fwd_suffix)$.begin())\n"); + diff.add_forward("for (range)$ next ("); + + rws += "copy (param_decl.name())$(ctx*.rws_suffix)$_iter := (range)$(ctx*.rws_suffix)$.rbegin())\n"; + rws += "for std::ranges::reverse_view((range)$) next ("; + diff.add_reverse_primal("for (range)$ next ("); if stmt.has_next() { // TODO: Assumption is here that nothing is in the next expression - diff += "(stmt.get_next_expression().to_string())$, "; + diff.add_forward("(stmt.get_next_expression().to_string())$, "); + diff.add_reverse_primal("(stmt.get_next_expression().to_string())$, "); + rws += "(reverse_next(stmt.get_next_expression().to_string()))$, "; } - diff += "(param_decl.name())$_d_iter++"; - diff += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; - diff += "((param_style)$ (param_decl.name())$(ctx*.fwd_suffix)$: (param_decl.type())$ = (param_decl.name())$_d_iter*)"; + diff.add_forward("(param_decl.name())$(ctx*.fwd_suffix)$_iter++"); + diff.add_forward(") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"); + rws += "(param_decl.name())$(ctx*.rws_suffix)$_iter++"; + rws += ") do ((param_style)$ (param_decl.name())$: (param_decl.type())$) {\n"; + rws += "(inout (param_decl.name())$(ctx*.rws_suffix)$ := (param_decl.name())$(ctx*.rws_suffix)$_iter*)\n"; + + diff.add_reverse_primal(") do ((param_style)$ (param_decl.name())$: (param_decl.type())$)"); + diff.add_forward("((param_style)$ (param_decl.name())$(ctx*.fwd_suffix)$: (param_decl.type())$ = (param_decl.name())$(ctx*.fwd_suffix)$_iter*)"); ctx*.add_variable_declaration("(param_decl.name())$", "(param_decl.type())$", true); // TODO: Handle loop/compound context variable declarations. + diff.add_reverse_backprop("}\n"); pre_traverse(stmt.get_for_body()); - diff += "}\n"; + diff.add_forward("}\n"); + + if stmt.has_next() { + diff.add_reverse_primal("(reverse_next(stmt.get_next_expression().to_string()))$;\n"); + } + diff.add_reverse_primal(rws_restore); + diff.add_reverse_primal("}\n"); + diff.add_reverse_backprop(rws); } } @@ -5626,8 +5723,34 @@ autodiff_stmt_handler: type = { h: autodiff_expression_handler = (ctx); h.pre_traverse(assignment_terms[1].get_term()); - h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); - append(h); + + is_overwrite := h.primal_expr.contains(h_lhs.primal_expr); + if overwrite_push_pop && is_overwrite { + r := ctx*.lookup_variable_declaration(h_lhs.primal_expr); + diff.add_reverse_primal("cpp2::ad_stack::push<(r.decl)$>((h_lhs.primal_expr)$);"); + } + + if is_overwrite && ctx*.is_reverse() { + t_b := ctx*.gen_temporary() + ctx*.rws_suffix; + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, t_b); + append(h); + diff.add_reverse_backprop("(h_lhs.rws_expr)$ = 0.0;\n"); + diff.add_reverse_backprop("(t_b)$ := (h_lhs.rws_expr)$;\n"); + } + else { + h.gen_assignment(h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); + append(h); + } + + if overwrite_push_pop && is_overwrite { + r := ctx*.lookup_variable_declaration(h_lhs.primal_expr); + diff.add_reverse_backprop("(h_lhs.primal_expr)$ = cpp2::ad_stack::pop<(r.decl)$>();"); + } + + // Simple overwrite check + if is_overwrite { + overwritten.push_back(h_lhs.primal_expr); + } } else { diff.add_forward(binexpr.to_string() + ";\n"); @@ -6046,6 +6169,9 @@ autodiff: (inout t: meta::type_declaration) = if 1 != order { t.add_runtime_support_include( "cpp2taylor.h" ); } + if reverse { + t.add_runtime_support_include( "cpp2ad_stack.h" ); + } ad_ctx.finish(); From 75b990b696df2ffae683ce2cb462741980c5fdab Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Fri, 5 Sep 2025 21:00:42 +0200 Subject: [PATCH 51/54] Temp. --- .../test-results/pure2-autodiff.cpp | 1 + source/reflect.h | 1385 +++++++++-------- 2 files changed, 775 insertions(+), 611 deletions(-) diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 14b64b179..20bd9f962 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -1,5 +1,6 @@ #define CPP2_IMPORT_STD Yes +#include "cpp2ad_stack.h" //=== Cpp2 type declarations ==================================================== diff --git a/source/reflect.h b/source/reflect.h index bedc15a21..42051d676 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -125,95 +125,95 @@ class autodiff_context; class autodiff_diff_code; -#line 4633 "reflect.h2" +#line 4634 "reflect.h2" class autodiff_activity_check; -#line 4731 "reflect.h2" +#line 4732 "reflect.h2" class autodiff_handler_base; -#line 4749 "reflect.h2" +#line 4750 "reflect.h2" class autodiff_expression_handler; -#line 5380 "reflect.h2" +#line 5382 "reflect.h2" class autodiff_stmt_handler; -#line 5729 "reflect.h2" +#line 5852 "reflect.h2" class autodiff_declaration_handler; -#line 6074 "reflect.h2" +#line 6200 "reflect.h2" class expression_flags; -#line 6090 "reflect.h2" +#line 6216 "reflect.h2" class regex_token; -#line 6117 "reflect.h2" +#line 6243 "reflect.h2" class regex_token_check; -#line 6138 "reflect.h2" +#line 6264 "reflect.h2" class regex_token_code; -#line 6159 "reflect.h2" +#line 6285 "reflect.h2" class regex_token_empty; -#line 6177 "reflect.h2" +#line 6303 "reflect.h2" class regex_token_list; -#line 6229 "reflect.h2" +#line 6355 "reflect.h2" class parse_context_group_state; -#line 6290 "reflect.h2" +#line 6416 "reflect.h2" class parse_context_branch_reset_state; -#line 6333 "reflect.h2" +#line 6459 "reflect.h2" class parse_context; -#line 6734 "reflect.h2" +#line 6860 "reflect.h2" class generation_function_context; -#line 6752 "reflect.h2" +#line 6878 "reflect.h2" class generation_context; -#line 6951 "reflect.h2" +#line 7077 "reflect.h2" class alternative_token; -#line 6966 "reflect.h2" +#line 7092 "reflect.h2" class alternative_token_gen; -#line 7031 "reflect.h2" +#line 7157 "reflect.h2" class any_token; -#line 7048 "reflect.h2" +#line 7174 "reflect.h2" class atomic_group_token; -#line 7078 "reflect.h2" +#line 7204 "reflect.h2" class char_token; -#line 7193 "reflect.h2" +#line 7319 "reflect.h2" class class_token; -#line 7417 "reflect.h2" +#line 7543 "reflect.h2" class group_ref_token; -#line 7554 "reflect.h2" +#line 7680 "reflect.h2" class group_token; -#line 7901 "reflect.h2" +#line 8027 "reflect.h2" class lookahead_lookbehind_token; -#line 7996 "reflect.h2" +#line 8122 "reflect.h2" class range_token; -#line 8153 "reflect.h2" +#line 8279 "reflect.h2" class special_range_token; -#line 8239 "reflect.h2" +#line 8365 "reflect.h2" template class regex_generator; -#line 8502 "reflect.h2" +#line 8628 "reflect.h2" } } @@ -1922,56 +1922,61 @@ class autodiff_diff_code { #line 4592 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& ; -#line 4596 "reflect.h2" +#line 4595 "reflect.h2" + public: autodiff_diff_code(autodiff_diff_code const& that); +#line 4595 "reflect.h2" + public: auto operator=(autodiff_diff_code const& that) -> autodiff_diff_code& ; +#line 4595 "reflect.h2" + public: autodiff_diff_code(autodiff_diff_code&& that) noexcept; +#line 4595 "reflect.h2" + public: auto operator=(autodiff_diff_code&& that) noexcept -> autodiff_diff_code& ; + public: auto add_forward(cpp2::impl::in v) & -> void; public: auto add_reverse_primal(cpp2::impl::in v) & -> void; public: auto add_reverse_backprop(cpp2::impl::in v) & -> void; public: auto reset() & -> void; -#line 4607 "reflect.h2" +#line 4608 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4613 "reflect.h2" +#line 4614 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4618 "reflect.h2" +#line 4619 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4623 "reflect.h2" +#line 4624 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; - public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(autodiff_diff_code const&) -> void = delete; - -#line 4626 "reflect.h2" +#line 4627 "reflect.h2" }; -#line 4633 "reflect.h2" +#line 4634 "reflect.h2" class autodiff_activity_check: public simple_traverser { -#line 4636 "reflect.h2" +#line 4637 "reflect.h2" public: autodiff_context* ctx; public: bool active {false}; public: autodiff_activity_check(cpp2::impl::in ctx_); -#line 4643 "reflect.h2" +#line 4644 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4655 "reflect.h2" +#line 4656 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4673 "reflect.h2" +#line 4674 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; -#line 4697 "reflect.h2" +#line 4698 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_activity_check(autodiff_activity_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_activity_check const&) -> void = delete; -#line 4729 "reflect.h2" +#line 4730 "reflect.h2" }; class autodiff_handler_base { @@ -1980,21 +1985,21 @@ class autodiff_handler_base { public: autodiff_diff_code diff; public: autodiff_handler_base(cpp2::impl::in ctx_); -#line 4736 "reflect.h2" +#line 4737 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& ; -#line 4742 "reflect.h2" +#line 4743 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4747 "reflect.h2" +#line 4748 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4753 "reflect.h2" +#line 4754 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -2003,31 +2008,33 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(cpp2::impl::in ctx_); -#line 4763 "reflect.h2" +#line 4764 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; -#line 4772 "reflect.h2" +#line 4773 "reflect.h2" public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; #line 4781 "reflect.h2" + public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs) const& -> std::string; + public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4792 "reflect.h2" +#line 4794 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4798 "reflect.h2" +#line 4800 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4810 "reflect.h2" +#line 4812 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4819 "reflect.h2" +#line 4821 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; @@ -2037,181 +2044,187 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; public: primal_fwd_rws_name(); -#line 4824 "reflect.h2" +#line 4826 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4835 "reflect.h2" +#line 4837 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4896 "reflect.h2" +#line 4898 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 5076 "reflect.h2" +#line 5078 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5121 "reflect.h2" +#line 5123 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5125 "reflect.h2" +#line 5127 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5129 "reflect.h2" +#line 5131 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5133 "reflect.h2" +#line 5135 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5137 "reflect.h2" +#line 5139 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5141 "reflect.h2" +#line 5143 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5145 "reflect.h2" +#line 5147 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5149 "reflect.h2" +#line 5151 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5153 "reflect.h2" +#line 5155 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5157 "reflect.h2" +#line 5159 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5161 "reflect.h2" +#line 5163 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5165 "reflect.h2" +#line 5167 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5196 "reflect.h2" +#line 5198 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5283 "reflect.h2" +#line 5285 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5287 "reflect.h2" +#line 5289 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5303 "reflect.h2" +#line 5305 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5343 "reflect.h2" +#line 5345 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5378 "reflect.h2" +#line 5380 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5384 "reflect.h2" +#line 5386 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; private: std::vector last_params {}; + private: std::vector overwritten {}; + + private: bool overwrite_push_pop {false}; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5395 "reflect.h2" - public: auto handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void; +#line 5400 "reflect.h2" + public: [[nodiscard]] auto handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code; -#line 5439 "reflect.h2" +#line 5442 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5444 "reflect.h2" +#line 5447 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5449 "reflect.h2" +#line 5452 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5500 "reflect.h2" +#line 5514 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5505 "reflect.h2" +#line 5519 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5510 "reflect.h2" +#line 5524 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5517 "reflect.h2" +#line 5531 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5524 "reflect.h2" +#line 5566 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5541 "reflect.h2" +#line 5582 "reflect.h2" + public: [[nodiscard]] auto reverse_next(cpp2::impl::in expr) const& -> std::string; + +#line 5597 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5598 "reflect.h2" +#line 5695 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5609 "reflect.h2" +#line 5706 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5613 "reflect.h2" +#line 5710 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5638 "reflect.h2" +#line 5761 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5642 "reflect.h2" +#line 5765 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5646 "reflect.h2" +#line 5769 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5650 "reflect.h2" +#line 5773 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5654 "reflect.h2" +#line 5777 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5658 "reflect.h2" +#line 5781 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5662 "reflect.h2" +#line 5785 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5666 "reflect.h2" +#line 5789 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5670 "reflect.h2" +#line 5793 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5674 "reflect.h2" +#line 5797 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5678 "reflect.h2" +#line 5801 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5682 "reflect.h2" +#line 5805 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5686 "reflect.h2" +#line 5809 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5691 "reflect.h2" +#line 5814 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5723 "reflect.h2" +#line 5846 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5727 "reflect.h2" +#line 5850 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5733 "reflect.h2" +#line 5856 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2221,37 +2234,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5745 "reflect.h2" +#line 5868 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5750 "reflect.h2" +#line 5873 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5908 "reflect.h2" +#line 6031 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5936 "reflect.h2" +#line 6059 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5960 "reflect.h2" +#line 6083 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5965 "reflect.h2" +#line 6088 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5968 "reflect.h2" +#line 6091 "reflect.h2" }; -#line 5971 "reflect.h2" +#line 6094 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 6070 "reflect.h2" +#line 6196 "reflect.h2" using error_func = std::function x)>; -#line 6074 "reflect.h2" +#line 6200 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2286,20 +2299,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 6082 "reflect.h2" +#line 6208 "reflect.h2" }; -#line 6090 "reflect.h2" +#line 6216 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 6098 "reflect.h2" +#line 6224 "reflect.h2" public: explicit regex_token(); -#line 6103 "reflect.h2" +#line 6229 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2311,103 +2324,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 6109 "reflect.h2" +#line 6235 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 6115 "reflect.h2" +#line 6241 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 6121 "reflect.h2" +#line 6247 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 6128 "reflect.h2" +#line 6254 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6132 "reflect.h2" +#line 6258 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6133 "reflect.h2" +#line 6259 "reflect.h2" }; -#line 6136 "reflect.h2" +#line 6262 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6142 "reflect.h2" +#line 6268 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6149 "reflect.h2" +#line 6275 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6153 "reflect.h2" +#line 6279 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6154 "reflect.h2" +#line 6280 "reflect.h2" }; -#line 6157 "reflect.h2" +#line 6283 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6163 "reflect.h2" +#line 6289 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6167 "reflect.h2" +#line 6293 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6171 "reflect.h2" +#line 6297 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6172 "reflect.h2" +#line 6298 "reflect.h2" }; -#line 6175 "reflect.h2" +#line 6301 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6181 "reflect.h2" +#line 6307 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6188 "reflect.h2" +#line 6314 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6194 "reflect.h2" +#line 6320 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6200 "reflect.h2" +#line 6326 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6208 "reflect.h2" +#line 6334 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2415,10 +2428,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6220 "reflect.h2" +#line 6346 "reflect.h2" }; -#line 6223 "reflect.h2" +#line 6349 "reflect.h2" // // Parse and generation context. // @@ -2434,33 +2447,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6243 "reflect.h2" +#line 6369 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6250 "reflect.h2" +#line 6376 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6262 "reflect.h2" +#line 6388 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6267 "reflect.h2" +#line 6393 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6271 "reflect.h2" +#line 6397 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6285 "reflect.h2" +#line 6411 "reflect.h2" }; -#line 6288 "reflect.h2" +#line 6414 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2473,25 +2486,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6306 "reflect.h2" +#line 6432 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6312 "reflect.h2" +#line 6438 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6319 "reflect.h2" +#line 6445 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6326 "reflect.h2" +#line 6452 "reflect.h2" }; -#line 6329 "reflect.h2" +#line 6455 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2507,7 +2520,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6345 "reflect.h2" +#line 6471 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2515,64 +2528,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6356 "reflect.h2" +#line 6482 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6369 "reflect.h2" +#line 6495 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6377 "reflect.h2" +#line 6503 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6381 "reflect.h2" +#line 6507 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6385 "reflect.h2" +#line 6511 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6397 "reflect.h2" +#line 6523 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6404 "reflect.h2" +#line 6530 "reflect.h2" public: auto next_alternative() & -> void; -#line 6410 "reflect.h2" +#line 6536 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6416 "reflect.h2" +#line 6542 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6420 "reflect.h2" +#line 6546 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6431 "reflect.h2" +#line 6557 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6435 "reflect.h2" +#line 6561 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6441 "reflect.h2" +#line 6567 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6445 "reflect.h2" +#line 6571 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6452 "reflect.h2" +#line 6578 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6463 "reflect.h2" +#line 6589 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2580,51 +2593,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6507 "reflect.h2" +#line 6633 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6519 "reflect.h2" +#line 6645 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6532 "reflect.h2" +#line 6658 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6555 "reflect.h2" +#line 6681 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6572 "reflect.h2" +#line 6698 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6593 "reflect.h2" +#line 6719 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6603 "reflect.h2" +#line 6729 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6607 "reflect.h2" +#line 6733 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6663 "reflect.h2" +#line 6789 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6702 "reflect.h2" +#line 6828 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6717 "reflect.h2" +#line 6843 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2636,10 +2649,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6728 "reflect.h2" +#line 6854 "reflect.h2" }; -#line 6731 "reflect.h2" +#line 6857 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2649,16 +2662,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6745 "reflect.h2" +#line 6871 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6748 "reflect.h2" +#line 6874 "reflect.h2" }; -#line 6751 "reflect.h2" +#line 6877 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2678,68 +2691,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6773 "reflect.h2" +#line 6899 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6779 "reflect.h2" +#line 6905 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6788 "reflect.h2" +#line 6914 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6799 "reflect.h2" +#line 6925 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6806 "reflect.h2" +#line 6932 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6826 "reflect.h2" +#line 6952 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6836 "reflect.h2" +#line 6962 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6859 "reflect.h2" +#line 6985 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6867 "reflect.h2" +#line 6993 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6871 "reflect.h2" +#line 6997 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6877 "reflect.h2" +#line 7003 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6883 "reflect.h2" +#line 7009 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6893 "reflect.h2" +#line 7019 "reflect.h2" public: auto finish_context() & -> void; -#line 6901 "reflect.h2" +#line 7027 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6907 "reflect.h2" +#line 7033 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6911 "reflect.h2" +#line 7037 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6915 "reflect.h2" +#line 7041 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6939 "reflect.h2" +#line 7065 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2747,7 +2760,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6945 "reflect.h2" +#line 7071 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2767,27 +2780,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6964 "reflect.h2" +#line 7090 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6970 "reflect.h2" +#line 7096 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6977 "reflect.h2" +#line 7103 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6994 "reflect.h2" +#line 7120 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 7001 "reflect.h2" +#line 7127 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 7014 "reflect.h2" +#line 7140 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2795,19 +2808,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 7026 "reflect.h2" +#line 7152 "reflect.h2" }; -#line 7029 "reflect.h2" +#line 7155 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 7035 "reflect.h2" +#line 7161 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 7039 "reflect.h2" +#line 7165 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2815,7 +2828,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 7044 "reflect.h2" +#line 7170 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2823,17 +2836,17 @@ class any_token class atomic_group_token : public regex_token { -#line 7052 "reflect.h2" +#line 7178 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7063 "reflect.h2" +#line 7189 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7071 "reflect.h2" +#line 7197 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2841,7 +2854,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 7074 "reflect.h2" +#line 7200 "reflect.h2" }; // Regex syntax: a @@ -2849,34 +2862,34 @@ class atomic_group_token class char_token : public regex_token { -#line 7082 "reflect.h2" +#line 7208 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7091 "reflect.h2" +#line 7217 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7097 "reflect.h2" +#line 7223 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7101 "reflect.h2" +#line 7227 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7124 "reflect.h2" +#line 7250 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7145 "reflect.h2" +#line 7271 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7163 "reflect.h2" +#line 7289 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7178 "reflect.h2" +#line 7304 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7184 "reflect.h2" +#line 7310 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2884,33 +2897,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7188 "reflect.h2" +#line 7314 "reflect.h2" }; -#line 7191 "reflect.h2" +#line 7317 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7197 "reflect.h2" +#line 7323 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7209 "reflect.h2" +#line 7335 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7335 "reflect.h2" +#line 7461 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7344 "reflect.h2" +#line 7470 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7349 "reflect.h2" +#line 7475 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2918,20 +2931,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7356 "reflect.h2" +#line 7482 "reflect.h2" }; -#line 7359 "reflect.h2" +#line 7485 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7400 "reflect.h2" +#line 7526 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7411 "reflect.h2" +#line 7537 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2941,20 +2954,20 @@ class class_token class group_ref_token : public regex_token { -#line 7421 "reflect.h2" +#line 7547 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7433 "reflect.h2" +#line 7559 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7534 "reflect.h2" +#line 7660 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7538 "reflect.h2" +#line 7664 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2962,10 +2975,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7541 "reflect.h2" +#line 7667 "reflect.h2" }; -#line 7544 "reflect.h2" +#line 7670 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2979,29 +2992,29 @@ class group_ref_token class group_token : public regex_token { -#line 7558 "reflect.h2" +#line 7684 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7580 "reflect.h2" +#line 7706 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7594 "reflect.h2" +#line 7720 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7753 "reflect.h2" +#line 7879 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7761 "reflect.h2" +#line 7887 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7779 "reflect.h2" +#line 7905 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7810 "reflect.h2" +#line 7936 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -3010,25 +3023,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7817 "reflect.h2" +#line 7943 "reflect.h2" }; -#line 7820 "reflect.h2" +#line 7946 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7861 "reflect.h2" +#line 7987 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7881 "reflect.h2" +#line 8007 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7897 "reflect.h2" +#line 8023 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3036,20 +3049,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7905 "reflect.h2" +#line 8031 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7914 "reflect.h2" +#line 8040 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7925 "reflect.h2" +#line 8051 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7932 "reflect.h2" +#line 8058 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3057,26 +3070,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7935 "reflect.h2" +#line 8061 "reflect.h2" }; -#line 7938 "reflect.h2" +#line 8064 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7966 "reflect.h2" +#line 8092 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7994 "reflect.h2" +#line 8120 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 8000 "reflect.h2" +#line 8126 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3086,22 +3099,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 8080 "reflect.h2" +#line 8206 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 8092 "reflect.h2" +#line 8218 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 8105 "reflect.h2" +#line 8231 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 8124 "reflect.h2" +#line 8250 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8134 "reflect.h2" +#line 8260 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8145 "reflect.h2" +#line 8271 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3109,16 +3122,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8148 "reflect.h2" +#line 8274 "reflect.h2" }; -#line 8151 "reflect.h2" +#line 8277 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8157 "reflect.h2" +#line 8283 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3127,7 +3140,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8187 "reflect.h2" +#line 8313 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3136,14 +3149,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8209 "reflect.h2" +#line 8335 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8231 "reflect.h2" +#line 8357 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3164,24 +3177,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8254 "reflect.h2" +#line 8380 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8289 "reflect.h2" +#line 8415 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8303 "reflect.h2" +#line 8429 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8315 "reflect.h2" +#line 8441 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8370 "reflect.h2" +#line 8496 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3192,7 +3205,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8502 "reflect.h2" +#line 8628 "reflect.h2" } } @@ -8485,15 +8498,41 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar #line 4594 "reflect.h2" } +#line 4595 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(autodiff_diff_code const& that) + : ctx{ that.ctx } + , fwd{ that.fwd } + , rws_primal{ that.rws_primal } + , rws_backprop{ that.rws_backprop }{} +#line 4595 "reflect.h2" + auto autodiff_diff_code::operator=(autodiff_diff_code const& that) -> autodiff_diff_code& { + ctx = that.ctx; + fwd = that.fwd; + rws_primal = that.rws_primal; + rws_backprop = that.rws_backprop; + return *this; } +#line 4595 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(autodiff_diff_code&& that) noexcept + : ctx{ std::move(that).ctx } + , fwd{ std::move(that).fwd } + , rws_primal{ std::move(that).rws_primal } + , rws_backprop{ std::move(that).rws_backprop }{} +#line 4595 "reflect.h2" + auto autodiff_diff_code::operator=(autodiff_diff_code&& that) noexcept -> autodiff_diff_code& { + ctx = std::move(that).ctx; + fwd = std::move(that).fwd; + rws_primal = std::move(that).rws_primal; + rws_backprop = std::move(that).rws_backprop; + return *this; } -#line 4596 "reflect.h2" - auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} #line 4597 "reflect.h2" - auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} + auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} #line 4598 "reflect.h2" + auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} +#line 4599 "reflect.h2" auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop = v + rws_backprop; }} -#line 4600 "reflect.h2" +#line 4601 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ fwd = ""; rws_primal = ""; @@ -8501,7 +8540,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4607 "reflect.h2" +#line 4608 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; @@ -8509,42 +8548,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4610 "reflect.h2" +#line 4611 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4613 "reflect.h2" +#line 4614 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4618 "reflect.h2" +#line 4619 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4623 "reflect.h2" +#line 4624 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4628 "reflect.h2" +#line 4629 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4639 "reflect.h2" +#line 4640 "reflect.h2" autodiff_activity_check::autodiff_activity_check(cpp2::impl::in ctx_) : simple_traverser{ } , ctx{ ctx_ }{ -#line 4641 "reflect.h2" +#line 4642 "reflect.h2" } -#line 4643 "reflect.h2" +#line 4644 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in t) -> void{ for ( auto const& m : CPP2_UFCS(get_members)(t) ) @@ -8557,7 +8596,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4655 "reflect.h2" +#line 4656 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in o) -> void{ auto type {o.type()}; @@ -8576,7 +8615,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4673 "reflect.h2" +#line 4674 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8601,7 +8640,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }}}} } -#line 4697 "reflect.h2" +#line 4698 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8610,7 +8649,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4704 "reflect.h2" +#line 4705 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8626,7 +8665,7 @@ auto i{0}; } // TODO: Really check for members -#line 4718 "reflect.h2" +#line 4719 "reflect.h2" if (!(is_func) || CPP2_UFCS(ssize)(terms) != 1) { active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))); } @@ -8639,39 +8678,39 @@ auto i{0}; } } -#line 4736 "reflect.h2" +#line 4737 "reflect.h2" autodiff_handler_base::autodiff_handler_base(cpp2::impl::in ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4739 "reflect.h2" +#line 4740 "reflect.h2" } -#line 4736 "reflect.h2" +#line 4737 "reflect.h2" auto autodiff_handler_base::operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4739 "reflect.h2" +#line 4740 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4742 "reflect.h2" +#line 4743 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff.fwd += o.diff.fwd; diff.rws_primal += o.diff.rws_primal; diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4759 "reflect.h2" +#line 4760 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(cpp2::impl::in ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4761 "reflect.h2" +#line 4762 "reflect.h2" } -#line 4763 "reflect.h2" +#line 4764 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8681,7 +8720,7 @@ auto i{0}; } } -#line 4772 "reflect.h2" +#line 4773 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ auto r {rhs_b}; r = string_util::replace_all(r, "_r_", lhs); @@ -8690,8 +8729,10 @@ auto i{0}; return r; } - #line 4781 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs) const& -> std::string { return prepare_backprop(rhs_b, lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix); } + +#line 4783 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8703,14 +8744,14 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4792 "reflect.h2" +#line 4794 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4794 "reflect.h2" +#line 4796 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4798 "reflect.h2" +#line 4800 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8723,13 +8764,13 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4810 "reflect.h2" +#line 4812 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4812 "reflect.h2" +#line 4814 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4814 "reflect.h2" +#line 4816 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } @@ -8741,7 +8782,7 @@ requires (std::is_convertible_v list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8751,7 +8792,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4835 "reflect.h2" +#line 4837 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8813,7 +8854,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} }} } -#line 4896 "reflect.h2" +#line 4898 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8821,7 +8862,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4902 "reflect.h2" +#line 4904 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8835,7 +8876,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4914 "reflect.h2" +#line 4916 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8860,7 +8901,7 @@ auto i{0}; { auto i{0}; -#line 4937 "reflect.h2" +#line 4939 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8885,7 +8926,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4960 "reflect.h2" +#line 4962 "reflect.h2" if (handle_special_function(object, object_d, object_b, function_name, args)) { return ; } @@ -9002,7 +9043,7 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 5076 "reflect.h2" +#line 5078 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; @@ -9030,7 +9071,7 @@ auto i{0}; { auto i{1}; -#line 5102 "reflect.h2" +#line 5104 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -9044,7 +9085,7 @@ auto i{1}; } } -#line 5114 "reflect.h2" +#line 5116 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); rws_expr = cpp2::move(code_rws); @@ -9052,62 +9093,62 @@ auto i{1}; return true; } -#line 5121 "reflect.h2" +#line 5123 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5125 "reflect.h2" +#line 5127 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5129 "reflect.h2" +#line 5131 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5133 "reflect.h2" +#line 5135 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5137 "reflect.h2" +#line 5139 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5141 "reflect.h2" +#line 5143 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5145 "reflect.h2" +#line 5147 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5149 "reflect.h2" +#line 5151 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5153 "reflect.h2" +#line 5155 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5157 "reflect.h2" +#line 5159 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5161 "reflect.h2" +#line 5163 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5165 "reflect.h2" +#line 5167 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9139,7 +9180,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5196 "reflect.h2" +#line 5198 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9210,7 +9251,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5267 "reflect.h2" +#line 5269 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9227,12 +9268,12 @@ auto i{1}; } } -#line 5283 "reflect.h2" +#line 5285 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5287 "reflect.h2" +#line 5289 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9249,7 +9290,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5303 "reflect.h2" +#line 5305 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9258,7 +9299,7 @@ auto i{1}; { auto i{0}; -#line 5310 "reflect.h2" +#line 5312 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9273,7 +9314,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5323 "reflect.h2" +#line 5325 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9294,7 +9335,7 @@ auto i{0}; } } -#line 5343 "reflect.h2" +#line 5345 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9331,22 +9372,22 @@ auto i{0}; }}}} } -#line 5390 "reflect.h2" +#line 5395 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5393 "reflect.h2" +#line 5398 "reflect.h2" } -#line 5395 "reflect.h2" - auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void{ +#line 5400 "reflect.h2" + [[nodiscard]] auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code{ + autodiff_diff_code r {ctx}; if (CPP2_UFCS(empty)(params)) { - return ; + return r; } - std::string fwd {"("}; for ( auto const& param : params ) { std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; std::string type {CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))}; @@ -9358,6 +9399,7 @@ auto i{0}; std::string init {""}; std::string init_d {""}; + // TODO: Add handling for reverse expressions if (CPP2_UFCS(has_initializer)(CPP2_UFCS(get_declaration)(param))) { autodiff_expression_handler ad {ctx}; @@ -9369,33 +9411,30 @@ auto i{0}; } } -#line 5424 "reflect.h2" - fwd += "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "; +#line 5430 "reflect.h2" + CPP2_UFCS(add_forward)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(init) + ", "); + CPP2_UFCS(add_reverse_primal)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "); if (ada.active) { - fwd += "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + cpp2::to_string(cpp2::move(init_d)) + ", "; + CPP2_UFCS(add_forward)(r, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + cpp2::to_string(cpp2::move(init_d)) + ", "); } CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type), cpp2::move(ada).active); } - if (!(leave_open)) { - fwd += ")"; - } - - diff += cpp2::move(fwd); + return r; } -#line 5439 "reflect.h2" +#line 5442 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5444 "reflect.h2" +#line 5447 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5449 "reflect.h2" +#line 5452 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9415,9 +9454,11 @@ auto i{0}; if (active) { auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + auto rws_ad_type {CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; std::string prim_init {""}; std::string fwd_init {""}; + std::string rws_init {""}; if (CPP2_UFCS(has_initializer)(o)) { autodiff_expression_handler ad {ctx}; @@ -9426,14 +9467,23 @@ auto i{0}; prim_init = " = " + ad.primal_expr; fwd_init = " = " + ad.fwd_expr; + rws_init = " = ()"; // TODO: Proper initialization. + + if (ad.rws_expr != "()") { + CPP2_UFCS(add_reverse_backprop)(diff, CPP2_UFCS(prepare_backprop)(ad, ad.rws_expr, lhs)); + } if (type == "_" && cpp2::move(ad).fwd_expr == "()") { // Special handling for auto initialization from a literal. fwd_init = " = " + CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; } } - diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; - diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; + + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(prim_init) + ";\n"); + + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(cpp2::move(rws_ad_type)) + cpp2::to_string(cpp2::move(rws_init)) + ";\n"); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"); } else { diff += "" + cpp2::to_string(lhs) + ": " + cpp2::to_string(type) + ""; @@ -9446,31 +9496,59 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5500 "reflect.h2" +#line 5514 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5505 "reflect.h2" +#line 5519 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5510 "reflect.h2" +#line 5524 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Remove this hack when statements like compound_statement can access their root statement. last_params = CPP2_UFCS(get_parameters)(stmt); base::traverse(stmt); } -#line 5517 "reflect.h2" +#line 5531 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - diff += "{\n"; - base::traverse(stmt); - diff += "}\n"; + autodiff_stmt_handler ad {ctx, mf}; + autodiff_stmt_handler ad_push_pop {ctx, mf}; + ad_push_pop.overwrite_push_pop = true; + + CPP2_UFCS(add_forward)(diff, "{\n"); + CPP2_UFCS(add_reverse_primal)(diff, "{\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "}\n"); + + for ( auto const& cur : CPP2_UFCS(get_statements)(stmt) ) { + CPP2_UFCS(pre_traverse)(ad, cur); + CPP2_UFCS(pre_traverse)(ad_push_pop, cur); + } + + for ( auto const& cur : ad.overwritten ) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cur)}; + CPP2_UFCS(add_reverse_primal)(diff, "cpp2::ad_stack::push<" + cpp2::to_string(cpp2::move(r).decl) + ">(" + cpp2::to_string(cur) + ");"); + } + + CPP2_UFCS(add_forward)(diff, ad.diff.fwd); + CPP2_UFCS(add_reverse_primal)(diff, ad.diff.rws_primal); + CPP2_UFCS(add_reverse_backprop)(diff, ad_push_pop.diff.rws_backprop); + CPP2_UFCS(add_reverse_backprop)(diff, cpp2::move(ad_push_pop).diff.rws_primal); + + for ( auto const& cur : cpp2::move(ad).overwritten ) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cur)}; + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(cur) + " = cpp2::ad_stack::pop<" + cpp2::to_string(cpp2::move(r).decl) + ">();"); + } + + CPP2_UFCS(add_forward)(diff, "}\n"); + CPP2_UFCS(add_reverse_primal)(diff, "}\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "{\n"); } -#line 5524 "reflect.h2" +#line 5566 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9487,13 +9565,33 @@ auto i{0}; } } -#line 5541 "reflect.h2" +#line 5582 "reflect.h2" + [[nodiscard]] auto autodiff_stmt_handler::reverse_next(cpp2::impl::in expr) const& -> std::string{ + if (CPP2_UFCS(contains)(expr, "+=")) { + return string_util::replace_all(expr, "+=", "-="); + } + else {if (CPP2_UFCS(contains)(expr, "-=")) { + return string_util::replace_all(expr, "-=", "+="); + }} + + CPP2_UFCS(error)(mf, "AD: Do not know how to reverse: " + cpp2::to_string(expr) + ""); + + return "Error"; + + } + +#line 5597 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - if (!(CPP2_UFCS(empty)(last_params))) { - handle_stmt_parameters(last_params, CPP2_UFCS(is_for)(stmt)); + auto diff_params {handle_stmt_parameters(last_params)}; + + if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx))) && (CPP2_UFCS(is_while)(stmt) || CPP2_UFCS(is_do)(stmt))) { + CPP2_UFCS(error)(stmt, "AD: Alpha limitiation now reverse mode for while or do while."); } if (CPP2_UFCS(is_while)(stmt)) { + if (!(CPP2_UFCS(empty)(last_params))) { + CPP2_UFCS(add_forward)(diff, "(" + cpp2::move(diff_params).fwd + ")"); + } // TODO: Assumption is here that nothing is in the condition diff += "while " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_do_while_condition)(stmt))) + " "; if (CPP2_UFCS(has_next)(stmt)) { @@ -9504,6 +9602,10 @@ auto i{0}; pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); } else {if (CPP2_UFCS(is_do)(stmt)) { + if (!(CPP2_UFCS(empty)(last_params))) { + CPP2_UFCS(add_forward)(diff, "(" + cpp2::move(diff_params).fwd + ")"); + } + // TODO: Assumption is here that nothing is in the condition diff += "do "; pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); @@ -9524,27 +9626,59 @@ auto i{0}; auto param {CPP2_UFCS(get_for_parameter)(stmt)}; auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; - if (CPP2_UFCS(empty)(last_params)) { - diff += "("; // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + + std::string rws {"("}; + std::string rws_restore {""}; + CPP2_UFCS(add_forward)(diff, "(");// Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + CPP2_UFCS(add_reverse_primal)(diff, "{\n"); + if (!(CPP2_UFCS(empty)(last_params))) { + for ( auto const& cur : last_params ) { + if (CPP2_UFCS(has_initializer)(CPP2_UFCS(get_declaration)(cur))) { + // TODO: Handle no type and no initializer. Handle passing style. + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ": " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + " = " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_initializer)(CPP2_UFCS(get_declaration)(cur)))) + ";\n"); + rws_restore += "cpp2::ad_stack::push<" + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + ">(" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ");\n"; + rws += "" + cpp2::to_string(to_string_view(CPP2_UFCS(get_passing_style)(cur))) + " " + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ": " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + " = cpp2::ad_stack::pop<" + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + ">(), "; + } + } + CPP2_UFCS(add_forward)(diff, cpp2::move(diff_params).fwd); } - diff += "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"; - diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; + CPP2_UFCS(add_forward)(diff, "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"); + CPP2_UFCS(add_forward)(diff, "for " + cpp2::to_string(range) + " next ("); + + rws += "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ".rbegin())\n"; + rws += "for std::ranges::reverse_view(" + cpp2::to_string(range) + ") next ("; + CPP2_UFCS(add_reverse_primal)(diff, "for " + cpp2::to_string(cpp2::move(range)) + " next ("); if (CPP2_UFCS(has_next)(stmt)) { // TODO: Assumption is here that nothing is in the next expression - diff += "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "); + rws += "" + cpp2::to_string(reverse_next(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt)))) + ", "; } - diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; - diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; - diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter++"); + CPP2_UFCS(add_forward)(diff, ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"); + rws += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter++"; + rws += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; + rws += "(inout " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " := " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter*)\n"; + + CPP2_UFCS(add_reverse_primal)(diff, ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ")"); + CPP2_UFCS(add_forward)(diff, "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter*)"); CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "", true);// TODO: Handle loop/compound context variable declarations. + CPP2_UFCS(add_reverse_backprop)(diff, "}\n"); pre_traverse(CPP2_UFCS(get_for_body)(stmt)); - diff += "}\n"; + CPP2_UFCS(add_forward)(diff, "}\n"); + + if (CPP2_UFCS(has_next)(stmt)) { + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(reverse_next(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt)))) + ";\n"); + } + CPP2_UFCS(add_reverse_primal)(diff, cpp2::move(rws_restore)); + CPP2_UFCS(add_reverse_primal)(diff, "}\n"); + CPP2_UFCS(add_reverse_backprop)(diff, cpp2::move(rws)); }} } -#line 5598 "reflect.h2" +#line 5695 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9556,12 +9690,12 @@ auto i{0}; } } -#line 5609 "reflect.h2" +#line 5706 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5613 "reflect.h2" +#line 5710 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9578,8 +9712,34 @@ auto i{0}; autodiff_expression_handler h {ctx}; CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, cpp2::move(h_lhs).rws_expr); - append(cpp2::move(h)); + + auto is_overwrite {CPP2_UFCS(contains)(h.primal_expr, h_lhs.primal_expr)}; + if (overwrite_push_pop && is_overwrite) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), h_lhs.primal_expr)}; + CPP2_UFCS(add_reverse_primal)(diff, "cpp2::ad_stack::push<" + cpp2::to_string(cpp2::move(r).decl) + ">(" + cpp2::to_string(h_lhs.primal_expr) + ");"); + } + + if (is_overwrite && CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) { + auto t_b {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx))) + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, t_b); + append(cpp2::move(h)); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(h_lhs.rws_expr) + " = 0.0;\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(cpp2::move(t_b)) + " := " + cpp2::to_string(h_lhs.rws_expr) + ";\n"); + } + else { + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); + append(cpp2::move(h)); + } + + if (overwrite_push_pop && is_overwrite) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), h_lhs.primal_expr)}; + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(h_lhs.primal_expr) + " = cpp2::ad_stack::pop<" + cpp2::to_string(cpp2::move(r).decl) + ">();"); + } + + // Simple overwrite check + if (cpp2::move(is_overwrite)) { + CPP2_UFCS(push_back)(overwritten, cpp2::move(h_lhs).primal_expr); + } } else { CPP2_UFCS(add_forward)(diff, CPP2_UFCS(to_string)(binexpr) + ";\n"); @@ -9587,73 +9747,73 @@ auto i{0}; } } -#line 5638 "reflect.h2" +#line 5761 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5642 "reflect.h2" +#line 5765 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5646 "reflect.h2" +#line 5769 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5650 "reflect.h2" +#line 5773 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5654 "reflect.h2" +#line 5777 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5658 "reflect.h2" +#line 5781 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5662 "reflect.h2" +#line 5785 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5666 "reflect.h2" +#line 5789 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5670 "reflect.h2" +#line 5793 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5674 "reflect.h2" +#line 5797 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5678 "reflect.h2" +#line 5801 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5682 "reflect.h2" +#line 5805 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5686 "reflect.h2" +#line 5809 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5691 "reflect.h2" +#line 5814 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9662,7 +9822,7 @@ auto i{0}; { auto i{0}; -#line 5698 "reflect.h2" +#line 5821 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9677,7 +9837,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5711 "reflect.h2" +#line 5834 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9690,27 +9850,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5723 "reflect.h2" +#line 5846 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5740 "reflect.h2" +#line 5863 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5743 "reflect.h2" +#line 5866 "reflect.h2" } -#line 5745 "reflect.h2" +#line 5868 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5750 "reflect.h2" +#line 5873 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9840,10 +10000,10 @@ auto i{0}; return ; } -#line 5880 "reflect.h2" +#line 6003 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5883 "reflect.h2" +#line 6006 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9868,7 +10028,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5908 "reflect.h2" +#line 6031 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9896,7 +10056,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5936 "reflect.h2" +#line 6059 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9920,17 +10080,17 @@ auto i{0}; } } -#line 5960 "reflect.h2" +#line 6083 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5965 "reflect.h2" +#line 6088 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5971 "reflect.h2" +#line 6094 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9974,7 +10134,7 @@ auto autodiff(meta::type_declaration& t) -> void return ; } - autodiff_context ad_ctx {order, cpp2::move(reverse)}; + autodiff_context ad_ctx {order, reverse}; ad_ctx.fwd_suffix = cpp2::move(suffix); ad_ctx.rws_suffix = cpp2::move(rws_suffix); @@ -10009,6 +10169,9 @@ auto autodiff(meta::type_declaration& t) -> void if (1 != cpp2::move(order)) { CPP2_UFCS(add_runtime_support_include)(t, "cpp2taylor.h"); } + if (cpp2::move(reverse)) { + CPP2_UFCS(add_runtime_support_include)(t, "cpp2ad_stack.h"); + } CPP2_UFCS(finish)(ad_ctx); @@ -10106,7 +10269,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 6056 "reflect.h2" +#line 6182 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -10122,11 +10285,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 6072 "reflect.h2" +#line 6198 "reflect.h2" // Possible modifiers for a regular expression. // -#line 6076 "reflect.h2" +#line 6202 "reflect.h2" // mod: i // mod: m // mod: s @@ -10134,116 +10297,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 6085 "reflect.h2" +#line 6211 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 6094 "reflect.h2" +#line 6220 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 6096 "reflect.h2" +#line 6222 "reflect.h2" } -#line 6098 "reflect.h2" +#line 6224 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 6100 "reflect.h2" +#line 6226 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 6106 "reflect.h2" +#line 6232 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 6107 "reflect.h2" +#line 6233 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 6108 "reflect.h2" +#line 6234 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 6123 "reflect.h2" +#line 6249 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 6126 "reflect.h2" +#line 6252 "reflect.h2" } -#line 6128 "reflect.h2" +#line 6254 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 6132 "reflect.h2" +#line 6258 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6144 "reflect.h2" +#line 6270 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6147 "reflect.h2" +#line 6273 "reflect.h2" } -#line 6149 "reflect.h2" +#line 6275 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6153 "reflect.h2" +#line 6279 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6163 "reflect.h2" +#line 6289 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6165 "reflect.h2" +#line 6291 "reflect.h2" } -#line 6167 "reflect.h2" +#line 6293 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6171 "reflect.h2" +#line 6297 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6183 "reflect.h2" +#line 6309 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6186 "reflect.h2" +#line 6312 "reflect.h2" } -#line 6188 "reflect.h2" +#line 6314 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6194 "reflect.h2" +#line 6320 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6200 "reflect.h2" +#line 6326 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10252,7 +10415,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6208 "reflect.h2" +#line 6334 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10268,7 +10431,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6236 "reflect.h2" +#line 6362 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10276,14 +10439,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6244 "reflect.h2" +#line 6370 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6251 "reflect.h2" +#line 6377 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10295,15 +10458,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6263 "reflect.h2" +#line 6389 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6268 "reflect.h2" +#line 6394 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6272 "reflect.h2" +#line 6398 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10324,7 +10487,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6298 "reflect.h2" +#line 6424 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10333,20 +10496,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6307 "reflect.h2" +#line 6433 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6313 "reflect.h2" +#line 6439 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6320 "reflect.h2" +#line 6446 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10361,16 +10524,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6350 "reflect.h2" +#line 6476 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6354 "reflect.h2" +#line 6480 "reflect.h2" } -#line 6360 "reflect.h2" +#line 6486 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10380,7 +10543,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6370 "reflect.h2" +#line 6496 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10388,17 +10551,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6377 "reflect.h2" +#line 6503 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6381 "reflect.h2" +#line 6507 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6388 "reflect.h2" +#line 6514 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10408,7 +10571,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6397 "reflect.h2" +#line 6523 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10416,24 +10579,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6404 "reflect.h2" +#line 6530 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6412 "reflect.h2" +#line 6538 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6416 "reflect.h2" +#line 6542 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6420 "reflect.h2" +#line 6546 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10445,22 +10608,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6431 "reflect.h2" +#line 6557 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6437 "reflect.h2" +#line 6563 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6441 "reflect.h2" +#line 6567 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6445 "reflect.h2" +#line 6571 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10468,7 +10631,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6452 "reflect.h2" +#line 6578 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10480,10 +10643,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6465 "reflect.h2" +#line 6591 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6468 "reflect.h2" +#line 6594 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10523,7 +10686,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6508 "reflect.h2" +#line 6634 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10535,14 +10698,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6519 "reflect.h2" +#line 6645 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6520 "reflect.h2" +#line 6646 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6521 "reflect.h2" +#line 6647 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6523 "reflect.h2" +#line 6649 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10552,10 +10715,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6532 "reflect.h2" +#line 6658 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6534 "reflect.h2" +#line 6660 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10577,14 +10740,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6555 "reflect.h2" +#line 6681 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6556 "reflect.h2" +#line 6682 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6557 "reflect.h2" +#line 6683 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6559 "reflect.h2" +#line 6685 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10598,7 +10761,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6572 "reflect.h2" +#line 6698 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10620,7 +10783,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6593 "reflect.h2" +#line 6719 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10631,12 +10794,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6603 "reflect.h2" +#line 6729 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6604 "reflect.h2" +#line 6730 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6609 "reflect.h2" +#line 6735 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10691,7 +10854,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6663 "reflect.h2" +#line 6789 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10731,7 +10894,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6702 "reflect.h2" +#line 6828 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10747,21 +10910,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6719 "reflect.h2" +#line 6845 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6720 "reflect.h2" +#line 6846 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6721 "reflect.h2" +#line 6847 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6723 "reflect.h2" +#line 6849 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6738 "reflect.h2" +#line 6864 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10769,7 +10932,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6745 "reflect.h2" +#line 6871 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10779,22 +10942,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6763 "reflect.h2" +#line 6889 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6768 "reflect.h2" +#line 6894 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6774 "reflect.h2" +#line 6900 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6780 "reflect.h2" +#line 6906 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10803,7 +10966,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6788 "reflect.h2" +#line 6914 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10815,7 +10978,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6799 "reflect.h2" +#line 6925 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10823,7 +10986,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6806 "reflect.h2" +#line 6932 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10844,7 +11007,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6827 "reflect.h2" +#line 6953 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10854,7 +11017,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6837 "reflect.h2" +#line 6963 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10877,33 +11040,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6861 "reflect.h2" +#line 6987 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6867 "reflect.h2" +#line 6993 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6871 "reflect.h2" +#line 6997 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6877 "reflect.h2" +#line 7003 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6885 "reflect.h2" +#line 7011 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10912,7 +11075,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6893 "reflect.h2" +#line 7019 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10921,22 +11084,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6903 "reflect.h2" +#line 7029 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6907 "reflect.h2" +#line 7033 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6911 "reflect.h2" +#line 7037 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6915 "reflect.h2" +#line 7041 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10960,18 +11123,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6940 "reflect.h2" +#line 7066 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6955 "reflect.h2" +#line 7081 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6957 "reflect.h2" +#line 7083 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10982,15 +11145,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6972 "reflect.h2" +#line 7098 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6975 "reflect.h2" +#line 7101 "reflect.h2" } -#line 6977 "reflect.h2" +#line 7103 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -11008,7 +11171,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6994 "reflect.h2" +#line 7120 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -11016,7 +11179,7 @@ generation_function_context::generation_function_context(){} } } -#line 7001 "reflect.h2" +#line 7127 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -11030,7 +11193,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7014 "reflect.h2" +#line 7140 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -11046,14 +11209,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 7035 "reflect.h2" +#line 7161 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 7037 "reflect.h2" +#line 7163 "reflect.h2" } -#line 7039 "reflect.h2" +#line 7165 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -11062,11 +11225,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 7054 "reflect.h2" +#line 7180 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 7056 "reflect.h2" +#line 7182 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -11074,7 +11237,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7063 "reflect.h2" +#line 7189 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11083,37 +11246,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7071 "reflect.h2" +#line 7197 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 7085 "reflect.h2" +#line 7211 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7089 "reflect.h2" +#line 7215 "reflect.h2" } -#line 7091 "reflect.h2" +#line 7217 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7095 "reflect.h2" +#line 7221 "reflect.h2" } -#line 7097 "reflect.h2" +#line 7223 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 7101 "reflect.h2" +#line 7227 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -11122,14 +11285,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 7107 "reflect.h2" +#line 7233 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 7112 "reflect.h2" +#line 7238 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -11142,7 +11305,7 @@ size_t i{0}; } } -#line 7124 "reflect.h2" +#line 7250 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11164,7 +11327,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7145 "reflect.h2" +#line 7271 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11183,7 +11346,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7163 "reflect.h2" +#line 7289 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11199,14 +11362,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7178 "reflect.h2" +#line 7304 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7184 "reflect.h2" +#line 7310 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11214,19 +11377,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7201 "reflect.h2" +#line 7327 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7202 "reflect.h2" +#line 7328 "reflect.h2" { -#line 7207 "reflect.h2" +#line 7333 "reflect.h2" } -#line 7210 "reflect.h2" +#line 7336 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11352,7 +11515,7 @@ size_t i{0}; ); } -#line 7335 "reflect.h2" +#line 7461 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11362,13 +11525,13 @@ size_t i{0}; ); } -#line 7344 "reflect.h2" +#line 7470 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7349 "reflect.h2" +#line 7475 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11379,12 +11542,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7361 "reflect.h2" +#line 7487 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7366 "reflect.h2" +#line 7492 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11418,7 +11581,7 @@ size_t i{0}; } -#line 7402 "reflect.h2" +#line 7528 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11427,19 +11590,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7425 "reflect.h2" +#line 7551 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7426 "reflect.h2" +#line 7552 "reflect.h2" { -#line 7431 "reflect.h2" +#line 7557 "reflect.h2" } -#line 7433 "reflect.h2" +#line 7559 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11541,19 +11704,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7534 "reflect.h2" +#line 7660 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7538 "reflect.h2" +#line 7664 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7562 "reflect.h2" +#line 7688 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11572,7 +11735,7 @@ size_t i{0}; return r; } -#line 7580 "reflect.h2" +#line 7706 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11587,7 +11750,7 @@ size_t i{0}; return r; } -#line 7594 "reflect.h2" +#line 7720 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11747,7 +11910,7 @@ size_t i{0}; } } -#line 7753 "reflect.h2" +#line 7879 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11756,7 +11919,7 @@ size_t i{0}; return r; } -#line 7761 "reflect.h2" +#line 7887 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11775,7 +11938,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7779 "reflect.h2" +#line 7905 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11807,7 +11970,7 @@ size_t i{0}; } } -#line 7810 "reflect.h2" +#line 7936 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11818,7 +11981,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7822 "reflect.h2" +#line 7948 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11857,7 +12020,7 @@ size_t i{0}; return r; } -#line 7863 "reflect.h2" +#line 7989 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11875,7 +12038,7 @@ size_t i{0}; }} } -#line 7883 "reflect.h2" +#line 8009 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11889,16 +12052,16 @@ size_t i{0}; } } -#line 7909 "reflect.h2" +#line 8035 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7912 "reflect.h2" +#line 8038 "reflect.h2" } -#line 7914 "reflect.h2" +#line 8040 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11910,7 +12073,7 @@ size_t i{0}; } } -#line 7925 "reflect.h2" +#line 8051 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11918,14 +12081,14 @@ size_t i{0}; return r; } -#line 7932 "reflect.h2" +#line 8058 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7940 "reflect.h2" +#line 8066 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11951,7 +12114,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7968 "reflect.h2" +#line 8094 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11977,11 +12140,11 @@ size_t i{0}; return r; } -#line 8005 "reflect.h2" +#line 8131 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 8007 "reflect.h2" +#line 8133 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12055,7 +12218,7 @@ size_t i{0}; return nullptr; } -#line 8080 "reflect.h2" +#line 8206 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -12068,7 +12231,7 @@ size_t i{0}; }} } -#line 8092 "reflect.h2" +#line 8218 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -12082,7 +12245,7 @@ size_t i{0}; }} } -#line 8105 "reflect.h2" +#line 8231 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -12102,7 +12265,7 @@ size_t i{0}; return r; } -#line 8124 "reflect.h2" +#line 8250 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -12113,7 +12276,7 @@ size_t i{0}; return r; } -#line 8134 "reflect.h2" +#line 8260 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -12125,14 +12288,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8145 "reflect.h2" +#line 8271 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8157 "reflect.h2" +#line 8283 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12156,7 +12319,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8181 "reflect.h2" +#line 8307 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12166,7 +12329,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8193 "reflect.h2" +#line 8319 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12182,7 +12345,7 @@ size_t i{0}; } } -#line 8213 "reflect.h2" +#line 8339 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12200,15 +12363,15 @@ size_t i{0}; }} } -#line 8249 "reflect.h2" +#line 8375 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8252 "reflect.h2" +#line 8378 "reflect.h2" } -#line 8254 "reflect.h2" +#line 8380 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12244,7 +12407,7 @@ size_t i{0}; return source; } -#line 8289 "reflect.h2" +#line 8415 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12260,7 +12423,7 @@ size_t i{0}; } } -#line 8305 "reflect.h2" +#line 8431 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12269,7 +12432,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12324,7 +12487,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8374 "reflect.h2" +#line 8500 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12452,7 +12615,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8502 "reflect.h2" +#line 8628 "reflect.h2" } } From 2b19b38ef5d8cc8e6743e745e0fc41fc0d4b4aa5 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sun, 7 Sep 2025 22:52:15 -0700 Subject: [PATCH 52/54] Build clean with GCC 10 and Clang 21, and update regression test results --- build_h2.bat | 1 + include/cpp2ad_stack.h | 38 + include/cpp2taylor.h | 4 +- include/cpp2taylor.h2 | 4 +- regression-tests/mixed-autodiff-taylor.cpp2 | 2 + .../mixed-autodiff-taylor.cpp.execution | 63 + .../pure2-autodiff-higher-order.cpp.execution | 240 +++ .../pure2-autodiff.cpp.execution | 46 + .../pure2-regex_20_lookbehind.cpp.execution | 58 + .../mixed-autodiff-taylor.cpp.execution | 63 + .../pure2-autodiff-higher-order.cpp.execution | 240 +++ .../gcc-10-c++20/pure2-autodiff.cpp.execution | 46 + .../pure2-regex_20_lookbehind.cpp.execution | 58 + .../mixed-autodiff-taylor.cpp.execution | 63 + .../pure2-autodiff-higher-order.cpp.execution | 240 +++ .../gcc-14-c++2b/pure2-autodiff.cpp.execution | 46 + .../pure2-regex_20_lookbehind.cpp.execution | 58 + .../test-results/mixed-autodiff-taylor.cpp | 10 +- .../mixed-autodiff-taylor.cpp.execution | 63 + .../mixed-autodiff-taylor.cpp.output | 1 + .../pure2-autodiff-higher-order.cpp.output | 15 + .../pure2-autodiff.cpp.execution | 46 + .../pure2-autodiff.cpp.output | 1 + .../pure2-regex_20_lookbehind.cpp.execution | 58 + .../pure2-regex_20_lookbehind.cpp.output | 1 + .../pure2-autodiff-higher-order.cpp | 174 +- .../pure2-autodiff-higher-order.cpp2.output | 27 +- .../test-results/pure2-autodiff.cpp | 1 + source/reflect.h | 1636 +++++++++-------- source/reflect.h2 | 62 +- 30 files changed, 2512 insertions(+), 853 deletions(-) create mode 100644 include/cpp2ad_stack.h create mode 100644 regression-tests/test-results/clang-12-c++20/mixed-autodiff-taylor.cpp.execution create mode 100644 regression-tests/test-results/clang-12-c++20/pure2-autodiff-higher-order.cpp.execution create mode 100644 regression-tests/test-results/clang-12-c++20/pure2-autodiff.cpp.execution create mode 100644 regression-tests/test-results/clang-12-c++20/pure2-regex_20_lookbehind.cpp.execution create mode 100644 regression-tests/test-results/gcc-10-c++20/mixed-autodiff-taylor.cpp.execution create mode 100644 regression-tests/test-results/gcc-10-c++20/pure2-autodiff-higher-order.cpp.execution create mode 100644 regression-tests/test-results/gcc-10-c++20/pure2-autodiff.cpp.execution create mode 100644 regression-tests/test-results/gcc-10-c++20/pure2-regex_20_lookbehind.cpp.execution create mode 100644 regression-tests/test-results/gcc-14-c++2b/mixed-autodiff-taylor.cpp.execution create mode 100644 regression-tests/test-results/gcc-14-c++2b/pure2-autodiff-higher-order.cpp.execution create mode 100644 regression-tests/test-results/gcc-14-c++2b/pure2-autodiff.cpp.execution create mode 100644 regression-tests/test-results/gcc-14-c++2b/pure2-regex_20_lookbehind.cpp.execution create mode 100644 regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.execution create mode 100644 regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.output create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff-higher-order.cpp.output create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.execution create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.execution create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.output diff --git a/build_h2.bat b/build_h2.bat index 080a89ff6..50e0da0c4 100644 --- a/build_h2.bat +++ b/build_h2.bat @@ -3,4 +3,5 @@ cd source cppfront reflect.h2 -verb %1 cd ..\include cppfront cpp2regex.h2 -verb %1 +cppfront cpp2taylor.h2 -verb %1 cd.. diff --git a/include/cpp2ad_stack.h b/include/cpp2ad_stack.h new file mode 100644 index 000000000..cdc13efaa --- /dev/null +++ b/include/cpp2ad_stack.h @@ -0,0 +1,38 @@ +#ifndef CPP2_CPP2AD_STACK_H +#define CPP2_CPP2AD_STACK_H + +#include + +namespace cpp2 { + +struct ad_stack { + + template + static void push(T const& v) { + std::vector& stack = get_stack(); + + stack.push_back(v); + } + + template + static T pop() { + std::vector& stack = get_stack(); + + T v = stack.back(); + stack.pop_back(); + + return v; + } + + private: + + template + static std::vector& get_stack() { + static std::vector stack = {}; + + return stack; + } +}; +} // cpp2 namespace + +#endif // CPP2_CPP2AD_STACK_H \ No newline at end of file diff --git a/include/cpp2taylor.h b/include/cpp2taylor.h index 636805d3f..34ab94f52 100644 --- a/include/cpp2taylor.h +++ b/include/cpp2taylor.h @@ -465,8 +465,8 @@ auto j{1}; #line 215 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { - CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * CPP2_UFCS(get)(c, k - j, c0); - CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * CPP2_UFCS(get)(s, k - j, s0); + CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * c.get(k - j, c0); + CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * s.get(k - j, s0); } } #line 219 "cpp2taylor.h2" diff --git a/include/cpp2taylor.h2 b/include/cpp2taylor.h2 index 95f4eb813..cf7f79efe 100644 --- a/include/cpp2taylor.h2 +++ b/include/cpp2taylor.h2 @@ -213,8 +213,8 @@ taylor: type = { while k <= dim next k += 1 { (copy j := 1) while j <= k next j += 1 { - s..v[k - 1] += j * u..get(j, u0) * c.get(k - j, c0); - c..v[k - 1] -= j * u..get(j, u0) * s.get(k - j, s0); + s..v[k - 1] += j * u..get(j, u0) * c..get(k - j, c0); + c..v[k - 1] -= j * u..get(j, u0) * s..get(k - j, s0); } s..v[k - 1] /= k; c..v[k - 1] /= k; diff --git a/regression-tests/mixed-autodiff-taylor.cpp2 b/regression-tests/mixed-autodiff-taylor.cpp2 index d7d4ff43c..17aa3fccb 100644 --- a/regression-tests/mixed-autodiff-taylor.cpp2 +++ b/regression-tests/mixed-autodiff-taylor.cpp2 @@ -61,6 +61,8 @@ test_cos: (x0: double, x: taylor) -> (y0: double, y: taylor) = { } write_output: (func: std::string, x: double, x_d: taylor, ret) = { + _ = x; + _ = x_d; std::cout << "(func)$ = (ret.y0)$" << std::endl; (copy i:=1) while i <= order next i += 1 { diff --git a/regression-tests/test-results/clang-12-c++20/mixed-autodiff-taylor.cpp.execution b/regression-tests/test-results/clang-12-c++20/mixed-autodiff-taylor.cpp.execution new file mode 100644 index 000000000..0a486b06f --- /dev/null +++ b/regression-tests/test-results/clang-12-c++20/mixed-autodiff-taylor.cpp.execution @@ -0,0 +1,63 @@ +x + x = 4.000000 +x + x diff order 1 = 2.000000 +x + x diff order 2 = 0.000000 +x + x diff order 3 = 0.000000 +x + x diff order 4 = 0.000000 +x + x diff order 5 = 0.000000 +x + x diff order 6 = 0.000000 +0 - x = -2.000000 +0 - x diff order 1 = -1.000000 +0 - x diff order 2 = 0.000000 +0 - x diff order 3 = 0.000000 +0 - x diff order 4 = 0.000000 +0 - x diff order 5 = 0.000000 +0 - x diff order 6 = 0.000000 +x^7 = 128.000000 +x^7 diff order 1 = 448.000000 +x^7 diff order 2 = 1344.000000 +x^7 diff order 3 = 3360.000000 +x^7 diff order 4 = 6720.000000 +x^7 diff order 5 = 10080.000000 +x^7 diff order 6 = 10080.000000 +1/x = 0.500000 +1/x diff order 1 = -0.250000 +1/x diff order 2 = 0.250000 +1/x diff order 3 = -0.375000 +1/x diff order 4 = 0.750000 +1/x diff order 5 = -1.875000 +1/x diff order 6 = 5.625000 +sqrt(x) = 1.414214 +sqrt(x) diff order 1 = 0.353553 +sqrt(x) diff order 2 = -0.088388 +sqrt(x) diff order 3 = 0.066291 +sqrt(x) diff order 4 = -0.082864 +sqrt(x) diff order 5 = 0.145012 +sqrt(x) diff order 6 = -0.326277 +log(x) = 0.693147 +log(x) diff order 1 = 0.500000 +log(x) diff order 2 = -0.250000 +log(x) diff order 3 = 0.250000 +log(x) diff order 4 = -0.375000 +log(x) diff order 5 = 0.750000 +log(x) diff order 6 = -1.875000 +exp(x) = 7.389056 +exp(x) diff order 1 = 7.389056 +exp(x) diff order 2 = 7.389056 +exp(x) diff order 3 = 7.389056 +exp(x) diff order 4 = 7.389056 +exp(x) diff order 5 = 7.389056 +exp(x) diff order 6 = 7.389056 +sin(x) = 0.909297 +sin(x) diff order 1 = -0.416147 +sin(x) diff order 2 = -0.909297 +sin(x) diff order 3 = 0.416147 +sin(x) diff order 4 = 0.909297 +sin(x) diff order 5 = -0.416147 +sin(x) diff order 6 = -0.909297 +cos(x) = -0.416147 +cos(x) diff order 1 = -0.909297 +cos(x) diff order 2 = 0.416147 +cos(x) diff order 3 = 0.909297 +cos(x) diff order 4 = -0.416147 +cos(x) diff order 5 = -0.909297 +cos(x) diff order 6 = 0.416147 diff --git a/regression-tests/test-results/clang-12-c++20/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/clang-12-c++20/pure2-autodiff-higher-order.cpp.execution new file mode 100644 index 000000000..84a5f58de --- /dev/null +++ b/regression-tests/test-results/clang-12-c++20/pure2-autodiff-higher-order.cpp.execution @@ -0,0 +1,240 @@ +diff(x + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y + x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 7.000000 + d1 = 4.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -1.000000 + d1 = -1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -3.000000 + d1 = -2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 6.000000 + d1 = 7.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y * x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 12.000000 + d1 = 20.000000 + d2 = 22.000000 + d3 = 12.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.666667 + d1 = -0.111111 + d2 = 0.148148 + d3 = -0.296296 + d4 = 0.790123 + d5 = -2.633745 + d6 = 10.534979 +diff(x / y / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.222222 + d1 = -0.185185 + d2 = 0.296296 + d3 = -0.691358 + d4 = 2.106996 + d5 = -7.901235 + d6 = 35.116598 +diff(x * y / x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * (x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 8.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(+x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(-x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 1.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -0.841471 + d1 = -0.540302 + d2 = 0.841471 + d3 = 0.540302 + d4 = -0.841471 + d5 = -0.540302 + d6 = 0.841471 +diff(if branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(if else branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(direct return) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate passive var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate untyped) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate default init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate no init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(do while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(for loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(tye_outer.a + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(type_outer.add(y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/clang-12-c++20/pure2-autodiff.cpp.execution b/regression-tests/test-results/clang-12-c++20/pure2-autodiff.cpp.execution new file mode 100644 index 000000000..863bd6bd5 --- /dev/null +++ b/regression-tests/test-results/clang-12-c++20/pure2-autodiff.cpp.execution @@ -0,0 +1,46 @@ +diff(x + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y + x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 7.000000, r_d = 4.000000) +diff(x - y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -1.000000, r_d = -1.000000) +diff(x - y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -3.000000, r_d = -2.000000) +diff(x + y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 6.000000, r_d = 7.000000) +diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 12.000000, r_d = 20.000000) +diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) +diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) +diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(+x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(-x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 1.000000, r_d = 1.000000) +diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate default init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x + y + x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 7.000000, x_b = 2.000000, y_b = 1.000000) +diff(x - y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -1.000000, x_b = 1.000000, y_b = -1.000000) +diff(x - y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -3.000000, x_b = 0.000000, y_b = -1.000000) +diff(x + y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) +diff(x * y * x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 12.000000, x_b = 12.000000, y_b = 4.000000) +diff(x / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.666667, x_b = 0.333333, y_b = -0.222222) +diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, x_b = 0.111111, y_b = -0.148148) +diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) +diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) +diff(x * func(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x * func_outer(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/clang-12-c++20/pure2-regex_20_lookbehind.cpp.execution b/regression-tests/test-results/clang-12-c++20/pure2-regex_20_lookbehind.cpp.execution new file mode 100644 index 000000000..cd61d4f56 --- /dev/null +++ b/regression-tests/test-results/clang-12-c++20/pure2-regex_20_lookbehind.cpp.execution @@ -0,0 +1,58 @@ +Running tests_20_lookbehind: +01_y: OK regex: (?<=a)b parsed_regex: (?<=a)b str: ab result_expr: $& expected_results b +02_y: OK regex: (?<=af?)b parsed_regex: (?<=af?)b str: ab result_expr: $& expected_results b +03_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: cb result_expr: - expected_results - +04_n: OK regex: (?<=a(?:fo)?)b parsed_regex: (?<=a(?:fo)?)b str: cb result_expr: - expected_results - +05_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: b result_expr: - expected_results - +06_n: OK regex: (?<=a(?:foo)?)b parsed_regex: (?<=a(?:foo)?)b str: b result_expr: - expected_results - +07_y: OK regex: (?)foo parsed_regex: (?<=bar>)foo str: bar>foo result_expr: $& expected_results foo +50_n: OK regex: (?)foo parsed_regex: (?)foo str: bar>foo result_expr: - expected_results - +51_y: OK regex: (?<=bar>ABC)foo parsed_regex: (?<=bar>ABC)foo str: bar>ABCfoo result_expr: $& expected_results foo +52_n: OK regex: (?ABC)foo parsed_regex: (?ABC)foo str: bar>ABCfoo result_expr: - expected_results - +53_y: OK regex: (?<=abcd(?<=(aaaabcd))) parsed_regex: (?<=abcd(?<=(aaaabcd))) str: ..aaaabcd.. result_expr: $1 expected_results aaaabcd +54_y: OK regex: (?=xy(?<=(aaxy))) parsed_regex: (?=xy(?<=(aaxy))) str: ..aaxy.. result_expr: $1 expected_results aaxy +55_y: OK regex: (?=xy(?<=(aaxyz?))) parsed_regex: (?=xy(?<=(aaxyz?))) str: ..aaxy.. result_expr: $1 expected_results aaxy +56_y: OK regex: (?<=(?=(aaxy))aa) parsed_regex: (?<=(?=(aaxy))aa) str: ..aaxy.. result_expr: $1 expected_results aaxy + diff --git a/regression-tests/test-results/gcc-10-c++20/mixed-autodiff-taylor.cpp.execution b/regression-tests/test-results/gcc-10-c++20/mixed-autodiff-taylor.cpp.execution new file mode 100644 index 000000000..0a486b06f --- /dev/null +++ b/regression-tests/test-results/gcc-10-c++20/mixed-autodiff-taylor.cpp.execution @@ -0,0 +1,63 @@ +x + x = 4.000000 +x + x diff order 1 = 2.000000 +x + x diff order 2 = 0.000000 +x + x diff order 3 = 0.000000 +x + x diff order 4 = 0.000000 +x + x diff order 5 = 0.000000 +x + x diff order 6 = 0.000000 +0 - x = -2.000000 +0 - x diff order 1 = -1.000000 +0 - x diff order 2 = 0.000000 +0 - x diff order 3 = 0.000000 +0 - x diff order 4 = 0.000000 +0 - x diff order 5 = 0.000000 +0 - x diff order 6 = 0.000000 +x^7 = 128.000000 +x^7 diff order 1 = 448.000000 +x^7 diff order 2 = 1344.000000 +x^7 diff order 3 = 3360.000000 +x^7 diff order 4 = 6720.000000 +x^7 diff order 5 = 10080.000000 +x^7 diff order 6 = 10080.000000 +1/x = 0.500000 +1/x diff order 1 = -0.250000 +1/x diff order 2 = 0.250000 +1/x diff order 3 = -0.375000 +1/x diff order 4 = 0.750000 +1/x diff order 5 = -1.875000 +1/x diff order 6 = 5.625000 +sqrt(x) = 1.414214 +sqrt(x) diff order 1 = 0.353553 +sqrt(x) diff order 2 = -0.088388 +sqrt(x) diff order 3 = 0.066291 +sqrt(x) diff order 4 = -0.082864 +sqrt(x) diff order 5 = 0.145012 +sqrt(x) diff order 6 = -0.326277 +log(x) = 0.693147 +log(x) diff order 1 = 0.500000 +log(x) diff order 2 = -0.250000 +log(x) diff order 3 = 0.250000 +log(x) diff order 4 = -0.375000 +log(x) diff order 5 = 0.750000 +log(x) diff order 6 = -1.875000 +exp(x) = 7.389056 +exp(x) diff order 1 = 7.389056 +exp(x) diff order 2 = 7.389056 +exp(x) diff order 3 = 7.389056 +exp(x) diff order 4 = 7.389056 +exp(x) diff order 5 = 7.389056 +exp(x) diff order 6 = 7.389056 +sin(x) = 0.909297 +sin(x) diff order 1 = -0.416147 +sin(x) diff order 2 = -0.909297 +sin(x) diff order 3 = 0.416147 +sin(x) diff order 4 = 0.909297 +sin(x) diff order 5 = -0.416147 +sin(x) diff order 6 = -0.909297 +cos(x) = -0.416147 +cos(x) diff order 1 = -0.909297 +cos(x) diff order 2 = 0.416147 +cos(x) diff order 3 = 0.909297 +cos(x) diff order 4 = -0.416147 +cos(x) diff order 5 = -0.909297 +cos(x) diff order 6 = 0.416147 diff --git a/regression-tests/test-results/gcc-10-c++20/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-10-c++20/pure2-autodiff-higher-order.cpp.execution new file mode 100644 index 000000000..84a5f58de --- /dev/null +++ b/regression-tests/test-results/gcc-10-c++20/pure2-autodiff-higher-order.cpp.execution @@ -0,0 +1,240 @@ +diff(x + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y + x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 7.000000 + d1 = 4.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -1.000000 + d1 = -1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -3.000000 + d1 = -2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 6.000000 + d1 = 7.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y * x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 12.000000 + d1 = 20.000000 + d2 = 22.000000 + d3 = 12.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.666667 + d1 = -0.111111 + d2 = 0.148148 + d3 = -0.296296 + d4 = 0.790123 + d5 = -2.633745 + d6 = 10.534979 +diff(x / y / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.222222 + d1 = -0.185185 + d2 = 0.296296 + d3 = -0.691358 + d4 = 2.106996 + d5 = -7.901235 + d6 = 35.116598 +diff(x * y / x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * (x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 8.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(+x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(-x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 1.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -0.841471 + d1 = -0.540302 + d2 = 0.841471 + d3 = 0.540302 + d4 = -0.841471 + d5 = -0.540302 + d6 = 0.841471 +diff(if branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(if else branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(direct return) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate passive var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate untyped) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate default init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate no init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(do while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(for loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(tye_outer.a + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(type_outer.add(y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/gcc-10-c++20/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-10-c++20/pure2-autodiff.cpp.execution new file mode 100644 index 000000000..863bd6bd5 --- /dev/null +++ b/regression-tests/test-results/gcc-10-c++20/pure2-autodiff.cpp.execution @@ -0,0 +1,46 @@ +diff(x + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y + x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 7.000000, r_d = 4.000000) +diff(x - y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -1.000000, r_d = -1.000000) +diff(x - y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -3.000000, r_d = -2.000000) +diff(x + y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 6.000000, r_d = 7.000000) +diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 12.000000, r_d = 20.000000) +diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) +diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) +diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(+x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(-x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 1.000000, r_d = 1.000000) +diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate default init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x + y + x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 7.000000, x_b = 2.000000, y_b = 1.000000) +diff(x - y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -1.000000, x_b = 1.000000, y_b = -1.000000) +diff(x - y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -3.000000, x_b = 0.000000, y_b = -1.000000) +diff(x + y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) +diff(x * y * x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 12.000000, x_b = 12.000000, y_b = 4.000000) +diff(x / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.666667, x_b = 0.333333, y_b = -0.222222) +diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, x_b = 0.111111, y_b = -0.148148) +diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) +diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) +diff(x * func(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x * func_outer(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/gcc-10-c++20/pure2-regex_20_lookbehind.cpp.execution b/regression-tests/test-results/gcc-10-c++20/pure2-regex_20_lookbehind.cpp.execution new file mode 100644 index 000000000..cd61d4f56 --- /dev/null +++ b/regression-tests/test-results/gcc-10-c++20/pure2-regex_20_lookbehind.cpp.execution @@ -0,0 +1,58 @@ +Running tests_20_lookbehind: +01_y: OK regex: (?<=a)b parsed_regex: (?<=a)b str: ab result_expr: $& expected_results b +02_y: OK regex: (?<=af?)b parsed_regex: (?<=af?)b str: ab result_expr: $& expected_results b +03_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: cb result_expr: - expected_results - +04_n: OK regex: (?<=a(?:fo)?)b parsed_regex: (?<=a(?:fo)?)b str: cb result_expr: - expected_results - +05_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: b result_expr: - expected_results - +06_n: OK regex: (?<=a(?:foo)?)b parsed_regex: (?<=a(?:foo)?)b str: b result_expr: - expected_results - +07_y: OK regex: (?)foo parsed_regex: (?<=bar>)foo str: bar>foo result_expr: $& expected_results foo +50_n: OK regex: (?)foo parsed_regex: (?)foo str: bar>foo result_expr: - expected_results - +51_y: OK regex: (?<=bar>ABC)foo parsed_regex: (?<=bar>ABC)foo str: bar>ABCfoo result_expr: $& expected_results foo +52_n: OK regex: (?ABC)foo parsed_regex: (?ABC)foo str: bar>ABCfoo result_expr: - expected_results - +53_y: OK regex: (?<=abcd(?<=(aaaabcd))) parsed_regex: (?<=abcd(?<=(aaaabcd))) str: ..aaaabcd.. result_expr: $1 expected_results aaaabcd +54_y: OK regex: (?=xy(?<=(aaxy))) parsed_regex: (?=xy(?<=(aaxy))) str: ..aaxy.. result_expr: $1 expected_results aaxy +55_y: OK regex: (?=xy(?<=(aaxyz?))) parsed_regex: (?=xy(?<=(aaxyz?))) str: ..aaxy.. result_expr: $1 expected_results aaxy +56_y: OK regex: (?<=(?=(aaxy))aa) parsed_regex: (?<=(?=(aaxy))aa) str: ..aaxy.. result_expr: $1 expected_results aaxy + diff --git a/regression-tests/test-results/gcc-14-c++2b/mixed-autodiff-taylor.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/mixed-autodiff-taylor.cpp.execution new file mode 100644 index 000000000..0a486b06f --- /dev/null +++ b/regression-tests/test-results/gcc-14-c++2b/mixed-autodiff-taylor.cpp.execution @@ -0,0 +1,63 @@ +x + x = 4.000000 +x + x diff order 1 = 2.000000 +x + x diff order 2 = 0.000000 +x + x diff order 3 = 0.000000 +x + x diff order 4 = 0.000000 +x + x diff order 5 = 0.000000 +x + x diff order 6 = 0.000000 +0 - x = -2.000000 +0 - x diff order 1 = -1.000000 +0 - x diff order 2 = 0.000000 +0 - x diff order 3 = 0.000000 +0 - x diff order 4 = 0.000000 +0 - x diff order 5 = 0.000000 +0 - x diff order 6 = 0.000000 +x^7 = 128.000000 +x^7 diff order 1 = 448.000000 +x^7 diff order 2 = 1344.000000 +x^7 diff order 3 = 3360.000000 +x^7 diff order 4 = 6720.000000 +x^7 diff order 5 = 10080.000000 +x^7 diff order 6 = 10080.000000 +1/x = 0.500000 +1/x diff order 1 = -0.250000 +1/x diff order 2 = 0.250000 +1/x diff order 3 = -0.375000 +1/x diff order 4 = 0.750000 +1/x diff order 5 = -1.875000 +1/x diff order 6 = 5.625000 +sqrt(x) = 1.414214 +sqrt(x) diff order 1 = 0.353553 +sqrt(x) diff order 2 = -0.088388 +sqrt(x) diff order 3 = 0.066291 +sqrt(x) diff order 4 = -0.082864 +sqrt(x) diff order 5 = 0.145012 +sqrt(x) diff order 6 = -0.326277 +log(x) = 0.693147 +log(x) diff order 1 = 0.500000 +log(x) diff order 2 = -0.250000 +log(x) diff order 3 = 0.250000 +log(x) diff order 4 = -0.375000 +log(x) diff order 5 = 0.750000 +log(x) diff order 6 = -1.875000 +exp(x) = 7.389056 +exp(x) diff order 1 = 7.389056 +exp(x) diff order 2 = 7.389056 +exp(x) diff order 3 = 7.389056 +exp(x) diff order 4 = 7.389056 +exp(x) diff order 5 = 7.389056 +exp(x) diff order 6 = 7.389056 +sin(x) = 0.909297 +sin(x) diff order 1 = -0.416147 +sin(x) diff order 2 = -0.909297 +sin(x) diff order 3 = 0.416147 +sin(x) diff order 4 = 0.909297 +sin(x) diff order 5 = -0.416147 +sin(x) diff order 6 = -0.909297 +cos(x) = -0.416147 +cos(x) diff order 1 = -0.909297 +cos(x) diff order 2 = 0.416147 +cos(x) diff order 3 = 0.909297 +cos(x) diff order 4 = -0.416147 +cos(x) diff order 5 = -0.909297 +cos(x) diff order 6 = 0.416147 diff --git a/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff-higher-order.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff-higher-order.cpp.execution new file mode 100644 index 000000000..84a5f58de --- /dev/null +++ b/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff-higher-order.cpp.execution @@ -0,0 +1,240 @@ +diff(x + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y + x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 7.000000 + d1 = 4.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -1.000000 + d1 = -1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x - y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -3.000000 + d1 = -2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + y - x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 6.000000 + d1 = 7.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * y * x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 12.000000 + d1 = 20.000000 + d2 = 22.000000 + d3 = 12.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.666667 + d1 = -0.111111 + d2 = 0.148148 + d3 = -0.296296 + d4 = 0.790123 + d5 = -2.633745 + d6 = 10.534979 +diff(x / y / y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 0.222222 + d1 = -0.185185 + d2 = 0.296296 + d3 = -0.691358 + d4 = 2.106996 + d5 = -7.901235 + d6 = 35.116598 +diff(x * y / x) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 3.000000 + d1 = 2.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * (x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x + x * y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 8.000000 + d2 = 4.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(+x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(-x + y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 1.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 10.000000 + d1 = 11.000000 + d2 = 6.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(sin(x - y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = -0.841471 + d1 = -0.540302 + d2 = 0.841471 + d3 = 0.540302 + d4 = -0.841471 + d5 = -0.540302 + d6 = 0.841471 +diff(if branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(if else branch) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 2.000000 + d1 = 1.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(direct return) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate passive var) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate untyped) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate default init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(intermediate no init) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(do while loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 8.000000 + d1 = 5.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(for loop) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(tye_outer.a + y) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 +diff(type_outer.add(y)) at (x = 2.000000, x_d = ( 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ), y = 3.000000, y_d = ( 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 )): + r = 5.000000 + d1 = 3.000000 + d2 = 0.000000 + d3 = 0.000000 + d4 = 0.000000 + d5 = 0.000000 + d6 = 0.000000 diff --git a/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff.cpp.execution new file mode 100644 index 000000000..863bd6bd5 --- /dev/null +++ b/regression-tests/test-results/gcc-14-c++2b/pure2-autodiff.cpp.execution @@ -0,0 +1,46 @@ +diff(x + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y + x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 7.000000, r_d = 4.000000) +diff(x - y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -1.000000, r_d = -1.000000) +diff(x - y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -3.000000, r_d = -2.000000) +diff(x + y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 6.000000, r_d = 7.000000) +diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 12.000000, r_d = 20.000000) +diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) +diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) +diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(+x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(-x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 1.000000, r_d = 1.000000) +diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate default init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x + y + x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 7.000000, x_b = 2.000000, y_b = 1.000000) +diff(x - y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -1.000000, x_b = 1.000000, y_b = -1.000000) +diff(x - y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -3.000000, x_b = 0.000000, y_b = -1.000000) +diff(x + y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) +diff(x * y * x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 12.000000, x_b = 12.000000, y_b = 4.000000) +diff(x / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.666667, x_b = 0.333333, y_b = -0.222222) +diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, x_b = 0.111111, y_b = -0.148148) +diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) +diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) +diff(x * func(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x * func_outer(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/gcc-14-c++2b/pure2-regex_20_lookbehind.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/pure2-regex_20_lookbehind.cpp.execution new file mode 100644 index 000000000..cd61d4f56 --- /dev/null +++ b/regression-tests/test-results/gcc-14-c++2b/pure2-regex_20_lookbehind.cpp.execution @@ -0,0 +1,58 @@ +Running tests_20_lookbehind: +01_y: OK regex: (?<=a)b parsed_regex: (?<=a)b str: ab result_expr: $& expected_results b +02_y: OK regex: (?<=af?)b parsed_regex: (?<=af?)b str: ab result_expr: $& expected_results b +03_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: cb result_expr: - expected_results - +04_n: OK regex: (?<=a(?:fo)?)b parsed_regex: (?<=a(?:fo)?)b str: cb result_expr: - expected_results - +05_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: b result_expr: - expected_results - +06_n: OK regex: (?<=a(?:foo)?)b parsed_regex: (?<=a(?:foo)?)b str: b result_expr: - expected_results - +07_y: OK regex: (?)foo parsed_regex: (?<=bar>)foo str: bar>foo result_expr: $& expected_results foo +50_n: OK regex: (?)foo parsed_regex: (?)foo str: bar>foo result_expr: - expected_results - +51_y: OK regex: (?<=bar>ABC)foo parsed_regex: (?<=bar>ABC)foo str: bar>ABCfoo result_expr: $& expected_results foo +52_n: OK regex: (?ABC)foo parsed_regex: (?ABC)foo str: bar>ABCfoo result_expr: - expected_results - +53_y: OK regex: (?<=abcd(?<=(aaaabcd))) parsed_regex: (?<=abcd(?<=(aaaabcd))) str: ..aaaabcd.. result_expr: $1 expected_results aaaabcd +54_y: OK regex: (?=xy(?<=(aaxy))) parsed_regex: (?=xy(?<=(aaxy))) str: ..aaxy.. result_expr: $1 expected_results aaxy +55_y: OK regex: (?=xy(?<=(aaxyz?))) parsed_regex: (?=xy(?<=(aaxyz?))) str: ..aaxy.. result_expr: $1 expected_results aaxy +56_y: OK regex: (?<=(?=(aaxy))aa) parsed_regex: (?<=(?=(aaxy))aa) str: ..aaxy.. result_expr: $1 expected_results aaxy + diff --git a/regression-tests/test-results/mixed-autodiff-taylor.cpp b/regression-tests/test-results/mixed-autodiff-taylor.cpp index 56a0606d4..0d9798c13 100644 --- a/regression-tests/test-results/mixed-autodiff-taylor.cpp +++ b/regression-tests/test-results/mixed-autodiff-taylor.cpp @@ -73,7 +73,7 @@ struct test_cos_ret { double y0; taylor y; }; #line 63 "mixed-autodiff-taylor.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, auto const& ret) -> void; -#line 71 "mixed-autodiff-taylor.cpp2" +#line 73 "mixed-autodiff-taylor.cpp2" auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -182,19 +182,21 @@ return { std::move(y0.value()), std::move(y.value()) }; } #line 63 "mixed-autodiff-taylor.cpp2" auto write_output(cpp2::impl::in func, cpp2::impl::in x, cpp2::impl::in x_d, auto const& ret) -> void{ + static_cast(x); + static_cast(x_d); std::cout << "" + cpp2::to_string(func) + " = " + cpp2::to_string(ret.y0) + "" << std::endl; { auto i{1}; -#line 66 "mixed-autodiff-taylor.cpp2" +#line 68 "mixed-autodiff-taylor.cpp2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { std::cout << "" + cpp2::to_string(func) + " diff order " + cpp2::to_string(i) + " = " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(ret.y, i)) + "" << std::endl; } } -#line 69 "mixed-autodiff-taylor.cpp2" +#line 71 "mixed-autodiff-taylor.cpp2" } -#line 71 "mixed-autodiff-taylor.cpp2" +#line 73 "mixed-autodiff-taylor.cpp2" auto main() -> int{ double x {2.0}; diff --git a/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.execution b/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.execution new file mode 100644 index 000000000..0a486b06f --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.execution @@ -0,0 +1,63 @@ +x + x = 4.000000 +x + x diff order 1 = 2.000000 +x + x diff order 2 = 0.000000 +x + x diff order 3 = 0.000000 +x + x diff order 4 = 0.000000 +x + x diff order 5 = 0.000000 +x + x diff order 6 = 0.000000 +0 - x = -2.000000 +0 - x diff order 1 = -1.000000 +0 - x diff order 2 = 0.000000 +0 - x diff order 3 = 0.000000 +0 - x diff order 4 = 0.000000 +0 - x diff order 5 = 0.000000 +0 - x diff order 6 = 0.000000 +x^7 = 128.000000 +x^7 diff order 1 = 448.000000 +x^7 diff order 2 = 1344.000000 +x^7 diff order 3 = 3360.000000 +x^7 diff order 4 = 6720.000000 +x^7 diff order 5 = 10080.000000 +x^7 diff order 6 = 10080.000000 +1/x = 0.500000 +1/x diff order 1 = -0.250000 +1/x diff order 2 = 0.250000 +1/x diff order 3 = -0.375000 +1/x diff order 4 = 0.750000 +1/x diff order 5 = -1.875000 +1/x diff order 6 = 5.625000 +sqrt(x) = 1.414214 +sqrt(x) diff order 1 = 0.353553 +sqrt(x) diff order 2 = -0.088388 +sqrt(x) diff order 3 = 0.066291 +sqrt(x) diff order 4 = -0.082864 +sqrt(x) diff order 5 = 0.145012 +sqrt(x) diff order 6 = -0.326277 +log(x) = 0.693147 +log(x) diff order 1 = 0.500000 +log(x) diff order 2 = -0.250000 +log(x) diff order 3 = 0.250000 +log(x) diff order 4 = -0.375000 +log(x) diff order 5 = 0.750000 +log(x) diff order 6 = -1.875000 +exp(x) = 7.389056 +exp(x) diff order 1 = 7.389056 +exp(x) diff order 2 = 7.389056 +exp(x) diff order 3 = 7.389056 +exp(x) diff order 4 = 7.389056 +exp(x) diff order 5 = 7.389056 +exp(x) diff order 6 = 7.389056 +sin(x) = 0.909297 +sin(x) diff order 1 = -0.416147 +sin(x) diff order 2 = -0.909297 +sin(x) diff order 3 = 0.416147 +sin(x) diff order 4 = 0.909297 +sin(x) diff order 5 = -0.416147 +sin(x) diff order 6 = -0.909297 +cos(x) = -0.416147 +cos(x) diff order 1 = -0.909297 +cos(x) diff order 2 = 0.416147 +cos(x) diff order 3 = 0.909297 +cos(x) diff order 4 = -0.416147 +cos(x) diff order 5 = -0.909297 +cos(x) diff order 6 = 0.416147 diff --git a/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.output new file mode 100644 index 000000000..fac16efc8 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/mixed-autodiff-taylor.cpp.output @@ -0,0 +1 @@ +mixed-autodiff-taylor.cpp diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff-higher-order.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff-higher-order.cpp.output new file mode 100644 index 000000000..f066190e5 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff-higher-order.cpp.output @@ -0,0 +1,15 @@ +pure2-autodiff-higher-order.cpp +C:\github\cppfront\include\cpp2util.h(1250): error C7595: 'std::source_location::current': call to immediate function is not a constant expression +C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\source_location(37): note: failure was caused by attempting to access a member on an object of dynamic type 'std::source_location' in which the member is not defined +C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\source_location(37): note: see usage of 'std::source_location::source_location' +C:\github\cppfront\include\cpp2util.h(1250): note: the call stack of the evaluation (the oldest call first) is +C:\github\cppfront\include\cpp2util.h(1250): note: while evaluating function 'std::source_location std::source_location::current(const uint_least32_t,const uint_least32_t,const char *const ,const char *const ) noexcept' +C:\github\cppfront\include\cpp2util.h(1250): note: the template instantiation context (the oldest one first) is +pure2-autodiff-higher-order.cpp2(14): note: see reference to class template instantiation 'cpp2::taylor' being compiled +cpp2taylor.h2(16): note: while compiling class template member function 'cpp2::taylor::taylor(const std::initializer_list &)' + with + [ + R=double + ] +pure2-autodiff-higher-order.cpp2(25): note: see the first reference to 'cpp2::taylor::taylor' in 'ad_name::func_outer_d' +cpp2taylor.h2(35): note: while compiling class template member function 'void cpp2::taylor::set(const int,const double) &' diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.execution b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.execution new file mode 100644 index 000000000..863bd6bd5 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.execution @@ -0,0 +1,46 @@ +diff(x + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y + x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 7.000000, r_d = 4.000000) +diff(x - y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -1.000000, r_d = -1.000000) +diff(x - y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -3.000000, r_d = -2.000000) +diff(x + y - x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 6.000000, r_d = 7.000000) +diff(x * y * x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 12.000000, r_d = 20.000000) +diff(x / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.666667, r_d = -0.111111) +diff(x / y / y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 0.222222, r_d = -0.185185) +diff(x * y / x) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 3.000000, r_d = 2.000000) +diff(x * (x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x + x * y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 8.000000) +diff(+x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(-x + y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 1.000000, r_d = 1.000000) +diff(x * func(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(x * func_outer(x, y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 10.000000, r_d = 11.000000) +diff(sin(x - y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = -0.841471, r_d = -0.540302) +diff(if branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(if else branch) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 2.000000, r_d = 1.000000) +diff(direct return) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate passive var) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate untyped) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate default init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(intermediate no init) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(do while loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 8.000000, r_d = 5.000000) +diff(for loop) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(tye_outer.a + y) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(type_outer.add(y)) at (x = 2.000000, x_d = 1.000000, y = 3.000000, y_d = 2.000000) = (r = 5.000000, r_d = 3.000000) +diff(x + y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 5.000000, x_b = 1.000000, y_b = 1.000000) +diff(x + y + x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 7.000000, x_b = 2.000000, y_b = 1.000000) +diff(x - y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -1.000000, x_b = 1.000000, y_b = -1.000000) +diff(x - y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -3.000000, x_b = 0.000000, y_b = -1.000000) +diff(x + y - x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 6.000000, x_b = 3.000000, y_b = 2.000000) +diff(x * y * x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 12.000000, x_b = 12.000000, y_b = 4.000000) +diff(x / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.666667, x_b = 0.333333, y_b = -0.222222) +diff(x / y / y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 0.222222, x_b = 0.111111, y_b = -0.148148) +diff(x * y / x) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 3.000000, x_b = 0.000000, y_b = 1.000000) +diff(x * (x + y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x + x * y) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 8.000000, x_b = 4.000000, y_b = 2.000000) +diff(sin(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = -0.841471, x_b = 0.540302, y_b = -0.540302) +diff(x * func(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +diff(x * func_outer(x-y)) at (x = 2.000000, y = 3.000000, r_b = 1.000000) = (r = 10.000000, x_b = 7.000000, y_b = 2.000000) +2nd order diff of x*x at 2.000000 = 2.000000 diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output new file mode 100644 index 000000000..32eadc310 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output @@ -0,0 +1 @@ +pure2-autodiff.cpp diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.execution b/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.execution new file mode 100644 index 000000000..cd61d4f56 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.execution @@ -0,0 +1,58 @@ +Running tests_20_lookbehind: +01_y: OK regex: (?<=a)b parsed_regex: (?<=a)b str: ab result_expr: $& expected_results b +02_y: OK regex: (?<=af?)b parsed_regex: (?<=af?)b str: ab result_expr: $& expected_results b +03_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: cb result_expr: - expected_results - +04_n: OK regex: (?<=a(?:fo)?)b parsed_regex: (?<=a(?:fo)?)b str: cb result_expr: - expected_results - +05_n: OK regex: (?<=a)b parsed_regex: (?<=a)b str: b result_expr: - expected_results - +06_n: OK regex: (?<=a(?:foo)?)b parsed_regex: (?<=a(?:foo)?)b str: b result_expr: - expected_results - +07_y: OK regex: (?)foo parsed_regex: (?<=bar>)foo str: bar>foo result_expr: $& expected_results foo +50_n: OK regex: (?)foo parsed_regex: (?)foo str: bar>foo result_expr: - expected_results - +51_y: OK regex: (?<=bar>ABC)foo parsed_regex: (?<=bar>ABC)foo str: bar>ABCfoo result_expr: $& expected_results foo +52_n: OK regex: (?ABC)foo parsed_regex: (?ABC)foo str: bar>ABCfoo result_expr: - expected_results - +53_y: OK regex: (?<=abcd(?<=(aaaabcd))) parsed_regex: (?<=abcd(?<=(aaaabcd))) str: ..aaaabcd.. result_expr: $1 expected_results aaaabcd +54_y: OK regex: (?=xy(?<=(aaxy))) parsed_regex: (?=xy(?<=(aaxy))) str: ..aaxy.. result_expr: $1 expected_results aaxy +55_y: OK regex: (?=xy(?<=(aaxyz?))) parsed_regex: (?=xy(?<=(aaxyz?))) str: ..aaxy.. result_expr: $1 expected_results aaxy +56_y: OK regex: (?<=(?=(aaxy))aa) parsed_regex: (?<=(?=(aaxy))aa) str: ..aaxy.. result_expr: $1 expected_results aaxy + diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.output new file mode 100644 index 000000000..14196f2d8 --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-regex_20_lookbehind.cpp.output @@ -0,0 +1 @@ +pure2-regex_20_lookbehind.cpp diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp b/regression-tests/test-results/pure2-autodiff-higher-order.cpp index 91b5ca793..118fe0fd0 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp @@ -383,14 +383,14 @@ return std::move(ret.value()); } } [[nodiscard]] auto type_outer::add_d(cpp2::impl::in this_d, cpp2::impl::in b, cpp2::impl::in> b_d) const& -> add_d_ret{ - double r {}; - cpp2::taylor r_d {};r_d = this_d.a_d + b_d; + double r {}; + cpp2::taylor r_d {};r_d = this_d.a_d + b_d; r = a + b; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto func_outer_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_d_ret{ - double ret {0.0}; - cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; + double ret {0.0}; + cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; ret = x + y; return { std::move(ret), std::move(ret_d) }; } @@ -665,68 +665,68 @@ return std::move(ret.value()); } return std::move(r.value()); } [[nodiscard]] auto ad_test::add_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_1_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d + y_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d + y_d + x_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d + x_d; r = x + y + x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_1_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d - y_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d - y_d; r = x - y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sub_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d - y_d - x_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d - y_d - x_d; r = x - y - x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_sub_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_sub_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d + y_d - x_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d + y_d - x_d; r = x + y - x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_1_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = CPP2_UFCS(mul)(x_d, y_d, x, y); + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d.mul(y_d, x, y); r = x * y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::mul_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {x_d.mul(y_d, x, y)}; auto temp_1 {x * y}; - r_d = CPP2_UFCS(mul)(cpp2::move(temp_1_d), x_d, temp_1, x); + r_d = cpp2::move(temp_1_d).mul(x_d, temp_1, x); r = cpp2::move(temp_1) * x; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_1_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_1_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = CPP2_UFCS(div)(x_d, y_d, x, y); + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = CPP2_UFCS(div)(x_d, y_d, x, y); r = x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> div_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; auto temp_1_d {CPP2_UFCS(div)(x_d, y_d, x, y)}; auto temp_1 {x / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(x),y)}; @@ -736,9 +736,9 @@ auto temp_1_d {CPP2_UFCS(div)(x_d, y_d, x, y)}; } [[nodiscard]] auto ad_test::mul_div_2_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_div_2_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +auto temp_1_d {x_d.mul(y_d, x, y)}; auto temp_1 {x * y}; r_d = CPP2_UFCS(div)(cpp2::move(temp_1_d), x_d, temp_1, x); @@ -747,20 +747,20 @@ auto temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; } [[nodiscard]] auto ad_test::mul_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> mul_add_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor temp_1_d {x_d + y_d}; double temp_1 {x + y}; - r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_1_d), x, temp_1); + r_d = x_d.mul(cpp2::move(temp_1_d), x, temp_1); r = x * cpp2::move(temp_1); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::add_mul_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> add_mul_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -cpp2::taylor temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +cpp2::taylor temp_1_d {x_d.mul(y_d, x, y)}; double temp_1 {x * y}; r_d = x_d + cpp2::move(temp_1_d); @@ -769,8 +769,8 @@ cpp2::taylor temp_1_d {CPP2_UFCS(mul)(x_d, y_d, x, y)}; } [[nodiscard]] auto ad_test::prefix_add_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_add_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor temp_1_d {+x_d}; double temp_1 {+x}; @@ -780,8 +780,8 @@ cpp2::taylor temp_1_d {+x_d}; } [[nodiscard]] auto ad_test::prefix_sub_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> prefix_sub_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor temp_1_d {-x_d}; double temp_1 {-x}; @@ -791,41 +791,41 @@ cpp2::taylor temp_1_d {-x_d}; } [[nodiscard]] auto ad_test::func_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_d_ret{ - double ret {0.0}; - cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; + double ret {0.0}; + cpp2::taylor ret_d {0.0};ret_d = x_d + y_d; ret = x + y; return { std::move(ret), std::move(ret_d) }; } [[nodiscard]] auto ad_test::func_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_call_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; auto temp_1 {func_d(x, x_d, y, y_d)}; - cpp2::taylor temp_2_d {temp_1.ret_d}; + cpp2::taylor temp_2_d {cpp2::move(temp_1).ret_d}; - double temp_2 {cpp2::move(temp_1).ret}; - r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_2_d), x, temp_2); + double temp_2 {func(x, y)}; + r_d = x_d.mul(cpp2::move(temp_2_d), x, temp_2); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::func_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> func_outer_call_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; auto temp_1 {func_outer_d(x, x_d, y, y_d)}; - cpp2::taylor temp_2_d {temp_1.ret_d}; + cpp2::taylor temp_2_d {cpp2::move(temp_1).ret_d}; - double temp_2 {cpp2::move(temp_1).ret}; - r_d = CPP2_UFCS(mul)(x_d, cpp2::move(temp_2_d), x, temp_2); + double temp_2 {func_outer(x, y)}; + r_d = x_d.mul(cpp2::move(temp_2_d), x, temp_2); r = x * cpp2::move(temp_2); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::sin_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> sin_call_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor temp_1_d {x_d - y_d}; double temp_1 {x - y}; @@ -835,8 +835,8 @@ cpp2::taylor temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::if_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_branch_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};r_d = x_d; + double r {0.0}; + cpp2::taylor r_d {0.0};r_d = x_d; r = x; if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; @@ -848,8 +848,8 @@ cpp2::taylor temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::if_else_branch_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> if_else_branch_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { + double r {0.0}; + cpp2::taylor r_d {0.0};if (cpp2::impl::cmp_less(x,0.0)) { r_d = y_d; r = y; } @@ -861,14 +861,14 @@ cpp2::taylor temp_1_d {x_d - y_d}; } [[nodiscard]] auto ad_test::direct_return_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> direct_return_d_ret{ - double r {}; - cpp2::taylor r_d {};r_d = x_d + y_d; + double r {}; + cpp2::taylor r_d {};r_d = x_d + y_d; r = x + y; return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::intermediate_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_var_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor t_d {x_d + y_d}; double t {x + y}; @@ -878,23 +878,19 @@ cpp2::taylor t_d {x_d + y_d}; } [[nodiscard]] auto ad_test::intermediate_passive_var_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_passive_var_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -int i_d {}; - - int i {}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i {}; r_d = x_d + y_d; r = x + y; - i_d = { }; i = 2; - static_cast(cpp2::move(i_d)); static_cast(cpp2::move(i)); return { std::move(r), std::move(r_d) }; } [[nodiscard]] auto ad_test::intermediate_untyped_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_untyped_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; auto t_d {cpp2::taylor()}; auto t {0.0}; @@ -906,8 +902,8 @@ auto t_d {cpp2::taylor()}; } [[nodiscard]] auto ad_test::intermediate_default_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_default_init_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::taylor t_d {}; double t {}; @@ -919,8 +915,8 @@ cpp2::taylor t_d {}; } [[nodiscard]] auto ad_test::intermediate_no_init_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> intermediate_no_init_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; cpp2::impl::deferred_init> t_d; cpp2::impl::deferred_init t; @@ -932,11 +928,9 @@ cpp2::impl::deferred_init> t_d; } [[nodiscard]] auto ad_test::while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> while_loop_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -int i_d {}; - - int i {0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i {0}; r_d = x_d; r = x; for( ; cpp2::impl::cmp_less(i,2); (i += 1) ) { @@ -947,11 +941,9 @@ int i_d {}; } [[nodiscard]] auto ad_test::do_while_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> do_while_loop_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; -int i_d {}; - - int i {0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; +int i {0}; r_d = x_d; r = x; do { @@ -967,8 +959,8 @@ int i_d {}; } [[nodiscard]] auto ad_test::for_loop_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> for_loop_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; std::vector> v_d {}; std::vector v {}; @@ -995,8 +987,8 @@ auto const& t_d{*cpp2::impl::assert_not_null(t_d_iter)}; } [[nodiscard]] auto ad_test::type_outer_use_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_use_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; type_outer_d t_d {}; type_outer t {}; @@ -1012,17 +1004,17 @@ type_outer_d t_d {}; } [[nodiscard]] auto ad_test::type_outer_call_d(cpp2::impl::in x, cpp2::impl::in> x_d, cpp2::impl::in y, cpp2::impl::in> y_d) -> type_outer_call_d_ret{ - double r {0.0}; - cpp2::taylor r_d {0.0}; + double r {0.0}; + cpp2::taylor r_d {0.0}; type_outer_d t_d {}; type_outer t {}; t_d.a_d = x_d; t.a = x; - auto temp_1 {CPP2_UFCS(add_d)(cpp2::move(t), cpp2::move(t_d), y, y_d)}; - r_d = temp_1.r_d; - r = cpp2::move(temp_1).r; + auto temp_1 {CPP2_UFCS(add_d)(t, cpp2::move(t_d), y, y_d)}; + r_d = cpp2::move(temp_1).r_d; + r = CPP2_UFCS(add)(cpp2::move(t), y); return { std::move(r), std::move(r_d) }; } diff --git a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output index 90bf689bd..17c5f140c 100644 --- a/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff-higher-order.cpp2.output @@ -411,7 +411,7 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - r_d = x_d.mul(y_d, x, y); + r_d = x_d..mul(y_d, x, y); r = x * y; return; } @@ -426,9 +426,9 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: _ = x_d.mul(y_d, x, y); + temp_1_d: _ = x_d..mul(y_d, x, y); temp_1: _ = x * y; - r_d = temp_1_d.mul(x_d, temp_1, x); + r_d = temp_1_d..mul(x_d, temp_1, x); r = temp_1 * x; return; } @@ -475,7 +475,7 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: _ = x_d.mul(y_d, x, y); + temp_1_d: _ = x_d..mul(y_d, x, y); temp_1: _ = x * y; r_d = temp_1_d.div(x_d, temp_1, x); r = temp_1 / x; @@ -494,7 +494,7 @@ ad_test:/* @autodiff<"order=6"> @print */ type = { temp_1_d: cpp2::taylor = x_d + y_d; temp_1: double = x + y; - r_d = x_d.mul(temp_1_d, x, temp_1); + r_d = x_d..mul(temp_1_d, x, temp_1); r = x * temp_1; return; } @@ -509,7 +509,7 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - temp_1_d: cpp2::taylor = x_d.mul(y_d, x, y); + temp_1_d: cpp2::taylor = x_d..mul(y_d, x, y); temp_1: double = x * y; r_d = x_d + temp_1_d; r = x + temp_1; @@ -577,8 +577,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = { temp_1: _ = func_d(x, x_d, y, y_d); temp_2_d: cpp2::taylor = temp_1.ret_d; - temp_2: double = temp_1.ret; - r_d = x_d.mul(temp_2_d, x, temp_2); + temp_2: double = func(x, y); + r_d = x_d..mul(temp_2_d, x, temp_2); r = x * temp_2; return; } @@ -595,8 +595,8 @@ ad_test:/* @autodiff<"order=6"> @print */ type = { temp_1: _ = func_outer_d(x, x_d, y, y_d); temp_2_d: cpp2::taylor = temp_1.ret_d; - temp_2: double = temp_1.ret; - r_d = x_d.mul(temp_2_d, x, temp_2); + temp_2: double = func_outer(x, y); + r_d = x_d..mul(temp_2_d, x, temp_2); r = x * temp_2; return; } @@ -706,13 +706,10 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - i_d: int = (); i: int = (); r_d = x_d + y_d; r = x + y; - i_d = (); i = 2; - _ = i_d; _ = i; return; } @@ -784,7 +781,6 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -807,7 +803,6 @@ ad_test:/* @autodiff<"order=6"> @print */ type = out r_d: cpp2::taylor = 0.0, ) = { - i_d: int = (); i: int = 0; r_d = x_d; r = x; @@ -890,7 +885,7 @@ ad_test:/* @autodiff<"order=6"> @print */ type = t.a = x; temp_1: _ = t.add_d(t_d, y, y_d); r_d = temp_1.r_d; - r = temp_1.r; + r = t.add(y); return; } } diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 14b64b179..20bd9f962 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -1,5 +1,6 @@ #define CPP2_IMPORT_STD Yes +#include "cpp2ad_stack.h" //=== Cpp2 type declarations ==================================================== diff --git a/source/reflect.h b/source/reflect.h index bedc15a21..979b6c095 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -117,103 +117,103 @@ class autodiff_declared_variable; #line 4171 "reflect.h2" class autodiff_declaration_stack_item; -#line 4210 "reflect.h2" +#line 4215 "reflect.h2" class autodiff_context; -#line 4585 "reflect.h2" +#line 4605 "reflect.h2" class autodiff_diff_code; -#line 4633 "reflect.h2" +#line 4654 "reflect.h2" class autodiff_activity_check; -#line 4731 "reflect.h2" +#line 4752 "reflect.h2" class autodiff_handler_base; -#line 4749 "reflect.h2" +#line 4770 "reflect.h2" class autodiff_expression_handler; -#line 5380 "reflect.h2" +#line 5402 "reflect.h2" class autodiff_stmt_handler; -#line 5729 "reflect.h2" +#line 5872 "reflect.h2" class autodiff_declaration_handler; -#line 6074 "reflect.h2" +#line 6220 "reflect.h2" class expression_flags; -#line 6090 "reflect.h2" +#line 6236 "reflect.h2" class regex_token; -#line 6117 "reflect.h2" +#line 6263 "reflect.h2" class regex_token_check; -#line 6138 "reflect.h2" +#line 6284 "reflect.h2" class regex_token_code; -#line 6159 "reflect.h2" +#line 6305 "reflect.h2" class regex_token_empty; -#line 6177 "reflect.h2" +#line 6323 "reflect.h2" class regex_token_list; -#line 6229 "reflect.h2" +#line 6375 "reflect.h2" class parse_context_group_state; -#line 6290 "reflect.h2" +#line 6436 "reflect.h2" class parse_context_branch_reset_state; -#line 6333 "reflect.h2" +#line 6479 "reflect.h2" class parse_context; -#line 6734 "reflect.h2" +#line 6880 "reflect.h2" class generation_function_context; -#line 6752 "reflect.h2" +#line 6898 "reflect.h2" class generation_context; -#line 6951 "reflect.h2" +#line 7097 "reflect.h2" class alternative_token; -#line 6966 "reflect.h2" +#line 7112 "reflect.h2" class alternative_token_gen; -#line 7031 "reflect.h2" +#line 7177 "reflect.h2" class any_token; -#line 7048 "reflect.h2" +#line 7194 "reflect.h2" class atomic_group_token; -#line 7078 "reflect.h2" +#line 7224 "reflect.h2" class char_token; -#line 7193 "reflect.h2" +#line 7339 "reflect.h2" class class_token; -#line 7417 "reflect.h2" +#line 7563 "reflect.h2" class group_ref_token; -#line 7554 "reflect.h2" +#line 7700 "reflect.h2" class group_token; -#line 7901 "reflect.h2" +#line 8047 "reflect.h2" class lookahead_lookbehind_token; -#line 7996 "reflect.h2" +#line 8142 "reflect.h2" class range_token; -#line 8153 "reflect.h2" +#line 8299 "reflect.h2" class special_range_token; -#line 8239 "reflect.h2" +#line 8385 "reflect.h2" template class regex_generator; -#line 8502 "reflect.h2" +#line 8648 "reflect.h2" } } @@ -344,7 +344,7 @@ template class reflection_base public: [[nodiscard]] auto print() const& -> std::string; public: [[nodiscard]] auto is_same(cpp2::impl::in o) const& -> bool; - public: template [[nodiscard]] auto is_same(reflection_base const& o) const& -> bool; + public: template [[nodiscard]] auto is_same([[maybe_unused]] reflection_base const& unnamed_param_2) const& -> bool; public: virtual ~reflection_base() noexcept; public: reflection_base(reflection_base const& that); public: reflection_base(reflection_base&& that) noexcept; @@ -1762,13 +1762,13 @@ struct lookup_variable_declaration_ret { bool found; autodiff_declared_variable public: autodiff_declaration_stack_item(autodiff_declaration_stack_item&& that) noexcept; -#line 4208 "reflect.h2" +#line 4213 "reflect.h2" }; class autodiff_context { private: int temporary_count {0}; -#line 4220 "reflect.h2" +#line 4225 "reflect.h2" public: std::vector special_funcs { autodiff_special_func("sin", 1, false, "sin(_a1_)", @@ -1808,13 +1808,13 @@ class autodiff_context { "_od_.push_back(_ad1_);", "TODO")}; -#line 4260 "reflect.h2" +#line 4265 "reflect.h2" public: std::string fwd_suffix {"_d"}; public: std::string rws_suffix {"_b"}; private: int order {1}; public: bool reverse {false}; -#line 4266 "reflect.h2" +#line 4271 "reflect.h2" public: std::string fwd_ad_type {"double"}; public: std::string rws_ad_type {"double"}; @@ -1824,91 +1824,91 @@ class autodiff_context { public: explicit autodiff_context(); public: autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_); -#line 4289 "reflect.h2" +#line 4294 "reflect.h2" public: auto add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member = false) & -> void; -#line 4293 "reflect.h2" +#line 4298 "reflect.h2" public: [[nodiscard]] auto is_variable_active(cpp2::impl::in name) & -> bool; -#line 4297 "reflect.h2" +#line 4302 "reflect.h2" public: auto create_namespace_stack(cpp2::impl::in t) & -> void; -#line 4314 "reflect.h2" +#line 4319 "reflect.h2" public: [[nodiscard]] auto is_forward() const& -> decltype(auto); public: [[nodiscard]] auto is_reverse() const& -> decltype(auto); public: [[nodiscard]] auto is_taylor() const& -> decltype(auto); public: [[nodiscard]] auto gen_temporary() & -> std::string; -#line 4323 "reflect.h2" +#line 4328 "reflect.h2" public: [[nodiscard]] auto is_type_active(cpp2::impl::in type) & -> bool; -#line 4344 "reflect.h2" +#line 4349 "reflect.h2" public: [[nodiscard]] auto get_fwd_ad_type(cpp2::impl::in type) & -> std::string; -#line 4362 "reflect.h2" +#line 4367 "reflect.h2" public: [[nodiscard]] auto get_rws_ad_type(cpp2::impl::in type) & -> std::string; -#line 4380 "reflect.h2" +#line 4385 "reflect.h2" public: [[nodiscard]] auto get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style; using lookup_declaration_ret = std::vector; -#line 4408 "reflect.h2" +#line 4413 "reflect.h2" public: [[nodiscard]] auto lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret; -#line 4431 "reflect.h2" +#line 4440 "reflect.h2" public: [[nodiscard]] auto lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable; using lookup_function_declaration_ret = std::vector; -#line 4448 "reflect.h2" +#line 4462 "reflect.h2" public: [[nodiscard]] auto lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret; using lookup_member_function_declaration_ret = std::vector; -#line 4458 "reflect.h2" +#line 4472 "reflect.h2" public: [[nodiscard]] auto lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret; using lookup_type_declaration_ret = std::vector; -#line 4468 "reflect.h2" +#line 4482 "reflect.h2" public: [[nodiscard]] auto lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret; struct lookup_special_function_handling_ret { bool m; std::string code_primal; std::string code_fwd; std::string code_rws; }; -#line 4478 "reflect.h2" +#line 4492 "reflect.h2" public: [[nodiscard]] auto lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret; -#line 4503 "reflect.h2" +#line 4517 "reflect.h2" public: auto add_as_differentiated(cpp2::impl::in t) & -> void; -#line 4511 "reflect.h2" +#line 4525 "reflect.h2" public: auto add_for_differentiation(cpp2::impl::in t) & -> void; -#line 4531 "reflect.h2" +#line 4551 "reflect.h2" public: [[nodiscard]] static auto is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool; -#line 4541 "reflect.h2" +#line 4561 "reflect.h2" public: auto enter_function() & -> void; -#line 4546 "reflect.h2" +#line 4566 "reflect.h2" public: auto leave_function() & -> void; -#line 4550 "reflect.h2" +#line 4570 "reflect.h2" public: auto push_stack(cpp2::impl::in decl) & -> void; -#line 4563 "reflect.h2" +#line 4583 "reflect.h2" public: auto pop_stack() & -> void; -#line 4578 "reflect.h2" +#line 4598 "reflect.h2" public: auto finish() & -> void; public: autodiff_context(autodiff_context const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_context const&) -> void = delete; -#line 4583 "reflect.h2" +#line 4603 "reflect.h2" }; class autodiff_diff_code { @@ -1919,59 +1919,64 @@ class autodiff_diff_code { public: std::string rws_backprop {""}; public: autodiff_diff_code(cpp2::impl::in ctx_); -#line 4592 "reflect.h2" +#line 4612 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& ; -#line 4596 "reflect.h2" +#line 4615 "reflect.h2" + public: autodiff_diff_code(autodiff_diff_code const& that); +#line 4615 "reflect.h2" + public: auto operator=(autodiff_diff_code const& that) -> autodiff_diff_code& ; +#line 4615 "reflect.h2" + public: autodiff_diff_code(autodiff_diff_code&& that) noexcept; +#line 4615 "reflect.h2" + public: auto operator=(autodiff_diff_code&& that) noexcept -> autodiff_diff_code& ; + public: auto add_forward(cpp2::impl::in v) & -> void; public: auto add_reverse_primal(cpp2::impl::in v) & -> void; public: auto add_reverse_backprop(cpp2::impl::in v) & -> void; public: auto reset() & -> void; -#line 4607 "reflect.h2" +#line 4628 "reflect.h2" public: auto operator=(cpp2::impl::in v) -> autodiff_diff_code& ; -#line 4613 "reflect.h2" +#line 4634 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4618 "reflect.h2" +#line 4639 "reflect.h2" public: auto operator+=(cpp2::impl::in v) & -> void; -#line 4623 "reflect.h2" +#line 4644 "reflect.h2" public: [[nodiscard]] auto empty() const& -> bool; - public: autodiff_diff_code(autodiff_diff_code const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(autodiff_diff_code const&) -> void = delete; - -#line 4626 "reflect.h2" +#line 4647 "reflect.h2" }; -#line 4633 "reflect.h2" +#line 4654 "reflect.h2" class autodiff_activity_check: public simple_traverser { -#line 4636 "reflect.h2" +#line 4657 "reflect.h2" public: autodiff_context* ctx; public: bool active {false}; public: autodiff_activity_check(cpp2::impl::in ctx_); -#line 4643 "reflect.h2" +#line 4664 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 4655 "reflect.h2" +#line 4676 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 4673 "reflect.h2" +#line 4694 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; -#line 4697 "reflect.h2" +#line 4718 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; public: autodiff_activity_check(autodiff_activity_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_activity_check const&) -> void = delete; -#line 4729 "reflect.h2" +#line 4750 "reflect.h2" }; class autodiff_handler_base { @@ -1980,21 +1985,21 @@ class autodiff_handler_base { public: autodiff_diff_code diff; public: autodiff_handler_base(cpp2::impl::in ctx_); -#line 4736 "reflect.h2" +#line 4757 "reflect.h2" public: auto operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& ; -#line 4742 "reflect.h2" +#line 4763 "reflect.h2" public: auto append(autodiff_handler_base const& o) & -> void; public: autodiff_handler_base(autodiff_handler_base const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_handler_base const&) -> void = delete; -#line 4747 "reflect.h2" +#line 4768 "reflect.h2" }; class autodiff_expression_handler: public simple_traverser, public autodiff_handler_base { -#line 4753 "reflect.h2" +#line 4774 "reflect.h2" public: using base = simple_traverser; public: std::string primal_expr {""}; @@ -2003,215 +2008,222 @@ class autodiff_expression_handler: public simple_traverser, public autodiff_hand public: autodiff_expression_handler(cpp2::impl::in ctx_); -#line 4763 "reflect.h2" +#line 4784 "reflect.h2" public: [[nodiscard]] auto add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string; -#line 4772 "reflect.h2" +#line 4793 "reflect.h2" public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string; -#line 4781 "reflect.h2" +#line 4801 "reflect.h2" + public: [[nodiscard]] auto prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs) const& -> std::string; + public: auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void; -#line 4792 "reflect.h2" +#line 4814 "reflect.h2" public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto); public: [[nodiscard]] auto gen_assignment(cpp2::impl::in lhs) & -> decltype(auto); -#line 4798 "reflect.h2" +#line 4820 "reflect.h2" public: auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void; -#line 4810 "reflect.h2" +#line 4832 "reflect.h2" public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto); public: [[nodiscard]] auto gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto); -#line 4819 "reflect.h2" +#line 4841 "reflect.h2" public: class primal_fwd_rws_name { public: std::string primal {""}; public: std::string fwd {""}; public: std::string rws {""}; public: bool active {false}; - public: primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_, auto&& active_) -CPP2_REQUIRES_ (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) ; + public: primal_fwd_rws_name(auto const& primal_, auto const& fwd_, auto const& rws_, auto const& active_); public: primal_fwd_rws_name(); -#line 4824 "reflect.h2" +#line 4846 "reflect.h2" }; public: [[nodiscard]] auto handle_expression_list(cpp2::impl::in list) & -> std::vector; -#line 4835 "reflect.h2" +#line 4857 "reflect.h2" public: [[nodiscard]] auto handle_expression_term(auto const& term) & -> primal_fwd_rws_name; -#line 4896 "reflect.h2" +#line 4918 "reflect.h2" public: auto handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void; -#line 5076 "reflect.h2" +#line 5098 "reflect.h2" public: [[nodiscard]] auto handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool; -#line 5121 "reflect.h2" +#line 5143 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5125 "reflect.h2" +#line 5147 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5129 "reflect.h2" +#line 5151 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5133 "reflect.h2" +#line 5155 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5137 "reflect.h2" +#line 5159 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5141 "reflect.h2" +#line 5163 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5145 "reflect.h2" +#line 5167 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5149 "reflect.h2" +#line 5171 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5153 "reflect.h2" +#line 5175 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5157 "reflect.h2" +#line 5179 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5161 "reflect.h2" +#line 5183 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5165 "reflect.h2" +#line 5187 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5196 "reflect.h2" +#line 5218 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5283 "reflect.h2" +#line 5305 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5287 "reflect.h2" +#line 5309 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5303 "reflect.h2" +#line 5325 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5343 "reflect.h2" +#line 5365 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5378 "reflect.h2" +#line 5400 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5384 "reflect.h2" +#line 5406 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; private: std::vector last_params {}; + private: std::vector overwritten {}; + + private: bool overwrite_push_pop {false}; public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5395 "reflect.h2" - public: auto handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void; +#line 5420 "reflect.h2" + public: [[nodiscard]] auto handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code; -#line 5439 "reflect.h2" +#line 5462 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5444 "reflect.h2" +#line 5467 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5449 "reflect.h2" +#line 5472 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5500 "reflect.h2" +#line 5534 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5505 "reflect.h2" +#line 5539 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5510 "reflect.h2" +#line 5544 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5517 "reflect.h2" +#line 5551 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5524 "reflect.h2" +#line 5586 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5541 "reflect.h2" +#line 5602 "reflect.h2" + public: [[nodiscard]] auto reverse_next(cpp2::impl::in expr) const& -> std::string; + +#line 5617 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5598 "reflect.h2" +#line 5715 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5609 "reflect.h2" +#line 5726 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5613 "reflect.h2" +#line 5730 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5638 "reflect.h2" +#line 5781 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5642 "reflect.h2" +#line 5785 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5646 "reflect.h2" +#line 5789 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5650 "reflect.h2" +#line 5793 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5654 "reflect.h2" +#line 5797 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5658 "reflect.h2" +#line 5801 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5662 "reflect.h2" +#line 5805 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5666 "reflect.h2" +#line 5809 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5670 "reflect.h2" +#line 5813 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5674 "reflect.h2" +#line 5817 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5678 "reflect.h2" +#line 5821 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5682 "reflect.h2" +#line 5825 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5686 "reflect.h2" +#line 5829 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5691 "reflect.h2" +#line 5834 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5723 "reflect.h2" +#line 5866 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5727 "reflect.h2" +#line 5870 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5733 "reflect.h2" +#line 5876 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2221,37 +2233,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5745 "reflect.h2" - public: auto traverse(cpp2::impl::in decl) -> void override; +#line 5888 "reflect.h2" + public: auto traverse(cpp2::impl::in decl_) -> void override; -#line 5750 "reflect.h2" +#line 5893 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5908 "reflect.h2" +#line 6051 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5936 "reflect.h2" +#line 6079 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5960 "reflect.h2" +#line 6103 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5965 "reflect.h2" +#line 6108 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 5968 "reflect.h2" +#line 6111 "reflect.h2" }; -#line 5971 "reflect.h2" +#line 6114 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 6070 "reflect.h2" +#line 6216 "reflect.h2" using error_func = std::function x)>; -#line 6074 "reflect.h2" +#line 6220 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2286,20 +2298,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 6082 "reflect.h2" +#line 6228 "reflect.h2" }; -#line 6090 "reflect.h2" +#line 6236 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 6098 "reflect.h2" +#line 6244 "reflect.h2" public: explicit regex_token(); -#line 6103 "reflect.h2" +#line 6249 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2311,103 +2323,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 6109 "reflect.h2" +#line 6255 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 6115 "reflect.h2" +#line 6261 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 6121 "reflect.h2" +#line 6267 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 6128 "reflect.h2" +#line 6274 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6132 "reflect.h2" +#line 6278 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6133 "reflect.h2" +#line 6279 "reflect.h2" }; -#line 6136 "reflect.h2" +#line 6282 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6142 "reflect.h2" +#line 6288 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6149 "reflect.h2" +#line 6295 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6153 "reflect.h2" +#line 6299 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6154 "reflect.h2" +#line 6300 "reflect.h2" }; -#line 6157 "reflect.h2" +#line 6303 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6163 "reflect.h2" +#line 6309 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6167 "reflect.h2" +#line 6313 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6171 "reflect.h2" +#line 6317 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6172 "reflect.h2" +#line 6318 "reflect.h2" }; -#line 6175 "reflect.h2" +#line 6321 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6181 "reflect.h2" +#line 6327 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6188 "reflect.h2" +#line 6334 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6194 "reflect.h2" +#line 6340 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6200 "reflect.h2" +#line 6346 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6208 "reflect.h2" +#line 6354 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2415,10 +2427,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6220 "reflect.h2" +#line 6366 "reflect.h2" }; -#line 6223 "reflect.h2" +#line 6369 "reflect.h2" // // Parse and generation context. // @@ -2434,33 +2446,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6243 "reflect.h2" +#line 6389 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6250 "reflect.h2" +#line 6396 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6262 "reflect.h2" +#line 6408 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6267 "reflect.h2" +#line 6413 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6271 "reflect.h2" +#line 6417 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6285 "reflect.h2" +#line 6431 "reflect.h2" }; -#line 6288 "reflect.h2" +#line 6434 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2473,25 +2485,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6306 "reflect.h2" +#line 6452 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6312 "reflect.h2" +#line 6458 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6319 "reflect.h2" +#line 6465 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6326 "reflect.h2" +#line 6472 "reflect.h2" }; -#line 6329 "reflect.h2" +#line 6475 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2507,7 +2519,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6345 "reflect.h2" +#line 6491 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2515,64 +2527,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6356 "reflect.h2" +#line 6502 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6369 "reflect.h2" +#line 6515 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6377 "reflect.h2" +#line 6523 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6381 "reflect.h2" +#line 6527 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6385 "reflect.h2" +#line 6531 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6397 "reflect.h2" +#line 6543 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6404 "reflect.h2" +#line 6550 "reflect.h2" public: auto next_alternative() & -> void; -#line 6410 "reflect.h2" +#line 6556 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6416 "reflect.h2" +#line 6562 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6420 "reflect.h2" +#line 6566 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6431 "reflect.h2" +#line 6577 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6435 "reflect.h2" +#line 6581 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6441 "reflect.h2" +#line 6587 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6445 "reflect.h2" +#line 6591 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6452 "reflect.h2" +#line 6598 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6463 "reflect.h2" +#line 6609 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2580,51 +2592,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6507 "reflect.h2" +#line 6653 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6519 "reflect.h2" +#line 6665 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6532 "reflect.h2" +#line 6678 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6555 "reflect.h2" +#line 6701 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6572 "reflect.h2" +#line 6718 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6593 "reflect.h2" +#line 6739 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6603 "reflect.h2" +#line 6749 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6607 "reflect.h2" +#line 6753 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6663 "reflect.h2" +#line 6809 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6702 "reflect.h2" +#line 6848 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6717 "reflect.h2" +#line 6863 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2636,10 +2648,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6728 "reflect.h2" +#line 6874 "reflect.h2" }; -#line 6731 "reflect.h2" +#line 6877 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2649,16 +2661,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6745 "reflect.h2" +#line 6891 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6748 "reflect.h2" +#line 6894 "reflect.h2" }; -#line 6751 "reflect.h2" +#line 6897 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2678,68 +2690,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6773 "reflect.h2" +#line 6919 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6779 "reflect.h2" +#line 6925 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6788 "reflect.h2" +#line 6934 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6799 "reflect.h2" +#line 6945 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6806 "reflect.h2" +#line 6952 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6826 "reflect.h2" +#line 6972 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6836 "reflect.h2" +#line 6982 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 6859 "reflect.h2" +#line 7005 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 6867 "reflect.h2" +#line 7013 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 6871 "reflect.h2" +#line 7017 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 6877 "reflect.h2" +#line 7023 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 6883 "reflect.h2" +#line 7029 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 6893 "reflect.h2" +#line 7039 "reflect.h2" public: auto finish_context() & -> void; -#line 6901 "reflect.h2" +#line 7047 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 6907 "reflect.h2" +#line 7053 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 6911 "reflect.h2" +#line 7057 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 6915 "reflect.h2" +#line 7061 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 6939 "reflect.h2" +#line 7085 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2747,7 +2759,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 6945 "reflect.h2" +#line 7091 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2767,27 +2779,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 6964 "reflect.h2" +#line 7110 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 6970 "reflect.h2" +#line 7116 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 6977 "reflect.h2" +#line 7123 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6994 "reflect.h2" +#line 7140 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 7001 "reflect.h2" +#line 7147 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 7014 "reflect.h2" +#line 7160 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2795,19 +2807,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 7026 "reflect.h2" +#line 7172 "reflect.h2" }; -#line 7029 "reflect.h2" +#line 7175 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 7035 "reflect.h2" +#line 7181 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 7039 "reflect.h2" +#line 7185 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2815,7 +2827,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 7044 "reflect.h2" +#line 7190 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2823,17 +2835,17 @@ class any_token class atomic_group_token : public regex_token { -#line 7052 "reflect.h2" +#line 7198 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7063 "reflect.h2" +#line 7209 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7071 "reflect.h2" +#line 7217 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2841,7 +2853,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 7074 "reflect.h2" +#line 7220 "reflect.h2" }; // Regex syntax: a @@ -2849,34 +2861,34 @@ class atomic_group_token class char_token : public regex_token { -#line 7082 "reflect.h2" +#line 7228 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7091 "reflect.h2" +#line 7237 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7097 "reflect.h2" +#line 7243 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7101 "reflect.h2" +#line 7247 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7124 "reflect.h2" +#line 7270 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7145 "reflect.h2" +#line 7291 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7163 "reflect.h2" +#line 7309 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7178 "reflect.h2" +#line 7324 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7184 "reflect.h2" +#line 7330 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2884,33 +2896,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7188 "reflect.h2" +#line 7334 "reflect.h2" }; -#line 7191 "reflect.h2" +#line 7337 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7197 "reflect.h2" +#line 7343 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7209 "reflect.h2" +#line 7355 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7335 "reflect.h2" +#line 7481 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7344 "reflect.h2" +#line 7490 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7349 "reflect.h2" +#line 7495 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2918,20 +2930,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7356 "reflect.h2" +#line 7502 "reflect.h2" }; -#line 7359 "reflect.h2" +#line 7505 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7400 "reflect.h2" +#line 7546 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7411 "reflect.h2" +#line 7557 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2941,20 +2953,20 @@ class class_token class group_ref_token : public regex_token { -#line 7421 "reflect.h2" +#line 7567 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7433 "reflect.h2" +#line 7579 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7534 "reflect.h2" +#line 7680 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7538 "reflect.h2" +#line 7684 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2962,10 +2974,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7541 "reflect.h2" +#line 7687 "reflect.h2" }; -#line 7544 "reflect.h2" +#line 7690 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2979,29 +2991,29 @@ class group_ref_token class group_token : public regex_token { -#line 7558 "reflect.h2" +#line 7704 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7580 "reflect.h2" +#line 7726 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7594 "reflect.h2" +#line 7740 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7753 "reflect.h2" +#line 7899 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7761 "reflect.h2" +#line 7907 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7779 "reflect.h2" +#line 7925 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7810 "reflect.h2" +#line 7956 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -3010,25 +3022,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7817 "reflect.h2" +#line 7963 "reflect.h2" }; -#line 7820 "reflect.h2" +#line 7966 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 7861 "reflect.h2" +#line 8007 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 7881 "reflect.h2" +#line 8027 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 7897 "reflect.h2" +#line 8043 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3036,20 +3048,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 7905 "reflect.h2" +#line 8051 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 7914 "reflect.h2" +#line 8060 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7925 "reflect.h2" +#line 8071 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7932 "reflect.h2" +#line 8078 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3057,26 +3069,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 7935 "reflect.h2" +#line 8081 "reflect.h2" }; -#line 7938 "reflect.h2" +#line 8084 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 7966 "reflect.h2" +#line 8112 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 7994 "reflect.h2" +#line 8140 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 8000 "reflect.h2" +#line 8146 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3086,22 +3098,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 8080 "reflect.h2" +#line 8226 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 8092 "reflect.h2" +#line 8238 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 8105 "reflect.h2" +#line 8251 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 8124 "reflect.h2" +#line 8270 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8134 "reflect.h2" +#line 8280 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8145 "reflect.h2" +#line 8291 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3109,16 +3121,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8148 "reflect.h2" +#line 8294 "reflect.h2" }; -#line 8151 "reflect.h2" +#line 8297 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8157 "reflect.h2" +#line 8303 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3127,7 +3139,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8187 "reflect.h2" +#line 8333 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3136,14 +3148,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8209 "reflect.h2" +#line 8355 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8231 "reflect.h2" +#line 8377 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3164,24 +3176,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8254 "reflect.h2" +#line 8400 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8289 "reflect.h2" +#line 8435 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8303 "reflect.h2" +#line 8449 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8315 "reflect.h2" +#line 8461 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8370 "reflect.h2" +#line 8516 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3192,7 +3204,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8502 "reflect.h2" +#line 8648 "reflect.h2" } } @@ -3462,7 +3474,7 @@ compiler_services::compiler_services(compiler_services&& that) noexcept #line 233 "reflect.h2" template [[nodiscard]] auto reflection_base::is_same(cpp2::impl::in o) const& -> bool { return n == o.n; }// Test pointers #line 234 "reflect.h2" - template template [[nodiscard]] auto reflection_base::is_same(reflection_base const& o) const& -> bool { return false; } + template template [[nodiscard]] auto reflection_base::is_same([[maybe_unused]] reflection_base const& unnamed_param_2) const& -> bool { return false; } template reflection_base::~reflection_base() noexcept{} template reflection_base::reflection_base(reflection_base const& that) @@ -7913,7 +7925,7 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in #line 4104 "reflect.h2" //----------------------------------------------------------------------- // -// autodiff - stub +// autodiff // #line 4121 "reflect.h2" @@ -8065,16 +8077,28 @@ auto sample_traverser(cpp2::impl::in idexpr, cpp2::impl::in [[nodiscard]] auto autodiff_declaration_stack_item::lookup_variable_declaration(cpp2::impl::in decl_name) const& -> lookup_variable_declaration_ret{ bool found {false}; autodiff_declared_variable r {}; -#line 4196 "reflect.h2" - for ( auto const& cur_context : std::ranges::views::reverse(declared_variables_stack) ) { - for ( auto const& cur : cur_context ) { +{ +auto cur_context{CPP2_UFCS(rbegin)(declared_variables_stack)}; + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + +#line 4199 "reflect.h2" + for( ; cur_context != CPP2_UFCS(rend)(declared_variables_stack); + ++cur_context ) + { + for ( auto const& cur : *cpp2::impl::assert_not_null(cur_context) ) { if (cur.name == decl_name) { found = true; r = cur; return { std::move(found), std::move(r) }; } } - }return { std::move(found), std::move(r) }; + } +} +#line 4200 "reflect.h2" + return { std::move(found), std::move(r) }; + +#line 4210 "reflect.h2" } autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declaration_stack_item const& that) @@ -8090,7 +8114,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar , diff_done{ std::move(that).diff_done } , declared_variables_stack{ std::move(that).declared_variables_stack }{} -#line 4213 "reflect.h2" +#line 4218 "reflect.h2" // Code in special function is replaced. Placeholders are: // _o_ : name of object for member functions. // _o_ : name of derivative object for member functions. @@ -8101,29 +8125,29 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar /* is_member = */ -#line 4230 "reflect.h2" +#line 4235 "reflect.h2" /* is_member = */ -#line 4238 "reflect.h2" +#line 4243 "reflect.h2" /* is_member = */ -#line 4246 "reflect.h2" +#line 4251 "reflect.h2" /* is_member = */ -#line 4254 "reflect.h2" +#line 4259 "reflect.h2" /* is_member = */ -#line 4265 "reflect.h2" +#line 4270 "reflect.h2" // Members depending on order -#line 4272 "reflect.h2" +#line 4277 "reflect.h2" autodiff_context::autodiff_context(){} -#line 4273 "reflect.h2" +#line 4278 "reflect.h2" autodiff_context::autodiff_context(cpp2::impl::in order_, cpp2::impl::in reverse_) : order{ order_ } , reverse{ reverse_ }{ -#line 4277 "reflect.h2" +#line 4282 "reflect.h2" if (1 != order) { if (reverse) { fwd_ad_type = "cpp2::taylor"; @@ -8136,17 +8160,17 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } -#line 4289 "reflect.h2" +#line 4294 "reflect.h2" auto autodiff_context::add_variable_declaration(cpp2::impl::in name, cpp2::impl::in type, cpp2::impl::in is_active, cpp2::impl::in is_member) & -> void{ CPP2_UFCS(push_back)(CPP2_UFCS(back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack), autodiff_declared_variable(name, type, is_active, is_member)); } -#line 4293 "reflect.h2" +#line 4298 "reflect.h2" [[nodiscard]] auto autodiff_context::is_variable_active(cpp2::impl::in name) & -> bool{ return lookup_variable_declaration(name).is_active; } -#line 4297 "reflect.h2" +#line 4302 "reflect.h2" auto autodiff_context::create_namespace_stack(cpp2::impl::in t) & -> void{ if (CPP2_UFCS(parent_is_nonglobal_namespace)(t)) { create_namespace_stack(CPP2_UFCS(as_nonglobal_namespace)(CPP2_UFCS(get_parent)(t))); @@ -8164,20 +8188,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar static_cast(CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), t))); } -#line 4314 "reflect.h2" +#line 4319 "reflect.h2" [[nodiscard]] auto autodiff_context::is_forward() const& -> decltype(auto) { return !(reverse) || (reverse && order != 1); } -#line 4315 "reflect.h2" +#line 4320 "reflect.h2" [[nodiscard]] auto autodiff_context::is_reverse() const& -> decltype(auto) { return reverse; } -#line 4316 "reflect.h2" +#line 4321 "reflect.h2" [[nodiscard]] auto autodiff_context::is_taylor() const& -> decltype(auto) { return order != 1; } -#line 4318 "reflect.h2" +#line 4323 "reflect.h2" [[nodiscard]] auto autodiff_context::gen_temporary() & -> std::string{ temporary_count += 1; return "temp_" + cpp2::to_string(temporary_count) + ""; } -#line 4323 "reflect.h2" +#line 4328 "reflect.h2" [[nodiscard]] auto autodiff_context::is_type_active(cpp2::impl::in type) & -> bool{ auto decls {lookup_type_declaration(type)}; auto r {false}; @@ -8199,7 +8223,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return r; } -#line 4344 "reflect.h2" +#line 4349 "reflect.h2" [[nodiscard]] auto autodiff_context::get_fwd_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8218,7 +8242,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", fwd_ad_type); } -#line 4362 "reflect.h2" +#line 4367 "reflect.h2" [[nodiscard]] auto autodiff_context::get_rws_ad_type(cpp2::impl::in type) & -> std::string{ auto type_d {type}; @@ -8237,7 +8261,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return string_util::replace_all(cpp2::move(type_d), "double", rws_ad_type); } -#line 4380 "reflect.h2" +#line 4385 "reflect.h2" [[nodiscard]] auto autodiff_context::get_reverse_passing_style(cpp2::impl::in p) const& -> passing_style{ // TODO: inspect does not work here: error: error: no matching function for call to ‘is(const cpp2::passing_style&)’ // return inspect p -> passing_style { @@ -8260,22 +8284,28 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar if (p == passing_style::forward) { return passing_style::inout; } if (p == passing_style::forward_ref) { return passing_style::inout; } -#line 4403 "reflect.h2" +#line 4408 "reflect.h2" CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Do not know how to handle passing style:" + cpp2::to_string(p) + ""); return passing_style::inout; } -#line 4408 "reflect.h2" +#line 4413 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_declaration(cpp2::impl::in decl_name) & -> lookup_declaration_ret{ std::vector r {}; -#line 4409 "reflect.h2" - for ( auto const& cur : std::ranges::views::reverse(declaration_stack) ) { +{ +auto cur{CPP2_UFCS(rbegin)(declaration_stack)}; + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ - std::string cur_full_name {cur.full_name + "::" + decl_name}; +#line 4417 "reflect.h2" + for( ; cur != CPP2_UFCS(rend)(declaration_stack); + ++cur ) + { + std::string cur_full_name {(*cpp2::impl::assert_not_null(cur)).full_name + "::" + decl_name}; auto ele {CPP2_UFCS(find)(declaration_map, cur_full_name)}; if (ele == CPP2_UFCS(end)(declaration_map)) { - ele = CPP2_UFCS(insert_or_assign)(declaration_map, cpp2::move(cur_full_name), CPP2_UFCS(lookup_declaration)(cur, decl_name)).first; + ele = CPP2_UFCS(insert_or_assign)(declaration_map, cpp2::move(cur_full_name), CPP2_UFCS(lookup_declaration)((*cpp2::impl::assert_not_null(cur)), decl_name)).first; } if (!(CPP2_UFCS(empty)((*cpp2::impl::assert_not_null(ele)).second))) { @@ -8288,32 +8318,44 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar // TODO: For overload resolution we may want to continue here and just add everything for all parent namespaces. } } +} +#line 4437 "reflect.h2" return r; } -#line 4431 "reflect.h2" +#line 4440 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_variable_declaration(cpp2::impl::in name) & -> autodiff_declared_variable{ if (name == "_") { return autodiff_declared_variable(name, "_", false, false); } +{ +auto cur_context{CPP2_UFCS(rbegin)(declaration_stack)}; - for ( auto const& cur_context : std::ranges::views::reverse(declaration_stack) ) { - auto r {CPP2_UFCS(lookup_variable_declaration)(cur_context, name)}; + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + +#line 4448 "reflect.h2" + for( ; cur_context != CPP2_UFCS(rend)(declaration_stack); + ++cur_context ) + { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(cur_context)), name)}; if (r.found) { return cpp2::move(r).r; } } +} +#line 4457 "reflect.h2" CPP2_UFCS(error)(CPP2_UFCS(back)(declaration_stack).decl, "AD: Could not find declaration of variable with name `" + cpp2::to_string(name) + "`."); return autodiff_declared_variable(); } -#line 4448 "reflect.h2" +#line 4462 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_function_declaration(cpp2::impl::in decl_name) & -> lookup_function_declaration_ret{ std::vector r {}; -#line 4449 "reflect.h2" +#line 4463 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8323,10 +8365,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4458 "reflect.h2" +#line 4472 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_member_function_declaration(cpp2::impl::in obj_type, cpp2::impl::in decl_name) & -> lookup_member_function_declaration_ret{ std::vector r {}; -#line 4459 "reflect.h2" +#line 4473 "reflect.h2" for ( auto const& cur : CPP2_UFCS(get_members)(obj_type) ) { if (CPP2_UFCS(is_function)(cur) && CPP2_UFCS(has_name)(cur) && decl_name == CPP2_UFCS(name)(cur)) { CPP2_UFCS(push_back)(r, CPP2_UFCS(as_function)(cur)); @@ -8336,10 +8378,10 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4468 "reflect.h2" +#line 4482 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_type_declaration(cpp2::impl::in decl_name) & -> lookup_type_declaration_ret{ std::vector r {}; -#line 4469 "reflect.h2" +#line 4483 "reflect.h2" auto r_all {lookup_declaration(decl_name)}; for ( auto const& cur : cpp2::move(r_all) ) { @@ -8349,13 +8391,13 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return r; } -#line 4478 "reflect.h2" +#line 4492 "reflect.h2" [[nodiscard]] auto autodiff_context::lookup_special_function_handling(cpp2::impl::in func_name, cpp2::impl::in n_args, cpp2::impl::in is_member) const& -> lookup_special_function_handling_ret{ cpp2::impl::deferred_init m; cpp2::impl::deferred_init code_primal; cpp2::impl::deferred_init code_fwd; cpp2::impl::deferred_init code_rws; -#line 4479 "reflect.h2" +#line 4493 "reflect.h2" autodiff_special_func lookup {func_name, n_args, is_member}; m.construct(false); @@ -8380,7 +8422,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }return { std::move(m.value()), std::move(code_primal.value()), std::move(code_fwd.value()), std::move(code_rws.value()) }; } -#line 4503 "reflect.h2" +#line 4517 "reflect.h2" auto autodiff_context::add_as_differentiated(cpp2::impl::in t) & -> void{ auto top {&CPP2_UFCS(back)(declaration_stack)}; @@ -8389,28 +8431,39 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cpp2::move(top))).diff_done, t); } -#line 4511 "reflect.h2" +#line 4525 "reflect.h2" auto autodiff_context::add_for_differentiation(cpp2::impl::in t) & -> void{ auto t_parent {CPP2_UFCS(get_parent)(t)}; auto found {false}; - for ( auto& cur : std::ranges::views::reverse(declaration_stack) ) { - if (CPP2_UFCS(is_same)(t_parent, cur.decl)) { - if (!(is_in_list(t, cur.diff_request))) { - CPP2_UFCS(push_back)(cur.diff_request, t); +{ +auto cur{CPP2_UFCS(rbegin)(declaration_stack)}; + + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + +#line 4533 "reflect.h2" + for( ; cur != CPP2_UFCS(rend)(declaration_stack); + ++cur ) + { + if (CPP2_UFCS(is_same)(t_parent, (*cpp2::impl::assert_not_null(cur)).decl)) { + if (!(is_in_list(t, (*cpp2::impl::assert_not_null(cur)).diff_request))) { + CPP2_UFCS(push_back)((*cpp2::impl::assert_not_null(cur)).diff_request, t); } found = true; break; } } +} +#line 4546 "reflect.h2" if (!(cpp2::move(found))) { CPP2_UFCS(error)(t, "AD: Could not find parent type/namespace for: " + cpp2::to_string(t) + ""); } } -#line 4531 "reflect.h2" +#line 4551 "reflect.h2" [[nodiscard]] auto autodiff_context::is_in_list(cpp2::impl::in v, cpp2::impl::in> list) -> bool{ for ( auto const& cur : list ) { if (CPP2_UFCS(is_same)(cur, v)) { @@ -8421,18 +8474,18 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar return false; } -#line 4541 "reflect.h2" +#line 4561 "reflect.h2" auto autodiff_context::enter_function() & -> void{ temporary_count = 0; CPP2_UFCS(push_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack, std::vector()); } -#line 4546 "reflect.h2" +#line 4566 "reflect.h2" auto autodiff_context::leave_function() & -> void{ CPP2_UFCS(pop_back)(CPP2_UFCS(back)(declaration_stack).declared_variables_stack); } -#line 4550 "reflect.h2" +#line 4570 "reflect.h2" auto autodiff_context::push_stack(cpp2::impl::in decl) & -> void{ std::string full_name {""}; @@ -8446,7 +8499,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(push_back)(declaration_stack, autodiff_declaration_stack_item(cpp2::move(full_name), decl)); } -#line 4563 "reflect.h2" +#line 4583 "reflect.h2" auto autodiff_context::pop_stack() & -> void{ if (cpp2::cpp2_default.is_active() && !(!(CPP2_UFCS(empty)(declaration_stack))) ) { cpp2::cpp2_default.report_violation(""); } @@ -8462,20 +8515,20 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar CPP2_UFCS(pop_back)(declaration_stack); } -#line 4578 "reflect.h2" +#line 4598 "reflect.h2" auto autodiff_context::finish() & -> void{ while( !(CPP2_UFCS(empty)(declaration_stack)) ) { pop_stack(); } } -#line 4592 "reflect.h2" +#line 4612 "reflect.h2" autodiff_diff_code::autodiff_diff_code(cpp2::impl::in ctx_) : ctx{ ctx_ }{ -#line 4594 "reflect.h2" +#line 4614 "reflect.h2" } -#line 4592 "reflect.h2" +#line 4612 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in ctx_) -> autodiff_diff_code& { ctx = ctx_; fwd = ""; @@ -8483,17 +8536,43 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4594 "reflect.h2" - } +#line 4614 "reflect.h2" + } +#line 4615 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(autodiff_diff_code const& that) + : ctx{ that.ctx } + , fwd{ that.fwd } + , rws_primal{ that.rws_primal } + , rws_backprop{ that.rws_backprop }{} +#line 4615 "reflect.h2" + auto autodiff_diff_code::operator=(autodiff_diff_code const& that) -> autodiff_diff_code& { + ctx = that.ctx; + fwd = that.fwd; + rws_primal = that.rws_primal; + rws_backprop = that.rws_backprop; + return *this; } +#line 4615 "reflect.h2" + autodiff_diff_code::autodiff_diff_code(autodiff_diff_code&& that) noexcept + : ctx{ std::move(that).ctx } + , fwd{ std::move(that).fwd } + , rws_primal{ std::move(that).rws_primal } + , rws_backprop{ std::move(that).rws_backprop }{} +#line 4615 "reflect.h2" + auto autodiff_diff_code::operator=(autodiff_diff_code&& that) noexcept -> autodiff_diff_code& { + ctx = std::move(that).ctx; + fwd = std::move(that).fwd; + rws_primal = std::move(that).rws_primal; + rws_backprop = std::move(that).rws_backprop; + return *this; } -#line 4596 "reflect.h2" +#line 4617 "reflect.h2" auto autodiff_diff_code::add_forward(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_forward)((*cpp2::impl::assert_not_null(ctx)))) {fwd += v;}} -#line 4597 "reflect.h2" +#line 4618 "reflect.h2" auto autodiff_diff_code::add_reverse_primal(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_primal += v;}} -#line 4598 "reflect.h2" +#line 4619 "reflect.h2" auto autodiff_diff_code::add_reverse_backprop(cpp2::impl::in v) & -> void{if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) {rws_backprop = v + rws_backprop; }} -#line 4600 "reflect.h2" +#line 4621 "reflect.h2" auto autodiff_diff_code::reset() & -> void{ fwd = ""; rws_primal = ""; @@ -8501,7 +8580,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4607 "reflect.h2" +#line 4628 "reflect.h2" auto autodiff_diff_code::operator=(cpp2::impl::in v) -> autodiff_diff_code& { ctx = ctx; fwd = v; @@ -8509,42 +8588,42 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar rws_backprop = ""; return *this; -#line 4610 "reflect.h2" +#line 4631 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4613 "reflect.h2" +#line 4634 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4618 "reflect.h2" +#line 4639 "reflect.h2" auto autodiff_diff_code::operator+=(cpp2::impl::in v) & -> void{ fwd += v.fwd; } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4623 "reflect.h2" +#line 4644 "reflect.h2" [[nodiscard]] auto autodiff_diff_code::empty() const& -> bool{ return CPP2_UFCS(empty)(fwd); } -#line 4628 "reflect.h2" +#line 4649 "reflect.h2" // // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. // to_string: (v: autodiff_diff_code) -> std::string = { // return v.fwd; // } -#line 4639 "reflect.h2" +#line 4660 "reflect.h2" autodiff_activity_check::autodiff_activity_check(cpp2::impl::in ctx_) : simple_traverser{ } , ctx{ ctx_ }{ -#line 4641 "reflect.h2" +#line 4662 "reflect.h2" } -#line 4643 "reflect.h2" +#line 4664 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in t) -> void{ for ( auto const& m : CPP2_UFCS(get_members)(t) ) @@ -8557,7 +8636,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4655 "reflect.h2" +#line 4676 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in o) -> void{ auto type {o.type()}; @@ -8576,7 +8655,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar } } -#line 4673 "reflect.h2" +#line 4694 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -8601,7 +8680,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar }}}} } -#line 4697 "reflect.h2" +#line 4718 "reflect.h2" auto autodiff_activity_check::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8610,7 +8689,7 @@ autodiff_declaration_stack_item::autodiff_declaration_stack_item(autodiff_declar { auto i{0}; -#line 4704 "reflect.h2" +#line 4725 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8626,7 +8705,7 @@ auto i{0}; } // TODO: Really check for members -#line 4718 "reflect.h2" +#line 4739 "reflect.h2" if (!(is_func) || CPP2_UFCS(ssize)(terms) != 1) { active |= CPP2_UFCS(is_variable_active)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(to_string)(CPP2_UFCS(get_primary_expression)(postfix))); } @@ -8639,39 +8718,39 @@ auto i{0}; } } -#line 4736 "reflect.h2" +#line 4757 "reflect.h2" autodiff_handler_base::autodiff_handler_base(cpp2::impl::in ctx_) : ctx{ ctx_ } , diff{ ctx }{ -#line 4739 "reflect.h2" +#line 4760 "reflect.h2" } -#line 4736 "reflect.h2" +#line 4757 "reflect.h2" auto autodiff_handler_base::operator=(cpp2::impl::in ctx_) -> autodiff_handler_base& { ctx = ctx_; diff = ctx; return *this; -#line 4739 "reflect.h2" +#line 4760 "reflect.h2" } // Temporary: TODO: remove when everything has been adapted to primal, fwd, rws pushes. -#line 4742 "reflect.h2" +#line 4763 "reflect.h2" auto autodiff_handler_base::append(autodiff_handler_base const& o) & -> void{ diff.fwd += o.diff.fwd; diff.rws_primal += o.diff.rws_primal; diff.rws_backprop = o.diff.rws_backprop + diff.rws_backprop; } -#line 4759 "reflect.h2" +#line 4780 "reflect.h2" autodiff_expression_handler::autodiff_expression_handler(cpp2::impl::in ctx_) : simple_traverser{ } , autodiff_handler_base{ ctx_ }{ -#line 4761 "reflect.h2" +#line 4782 "reflect.h2" } -#line 4763 "reflect.h2" +#line 4784 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::add_suffix_if_not_wildcard(cpp2::impl::in lhs, cpp2::impl::in suffix) const& -> std::string{ if ("_" == lhs) { return lhs; @@ -8681,7 +8760,7 @@ auto i{0}; } } -#line 4772 "reflect.h2" +#line 4793 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) const& -> std::string{ auto r {rhs_b}; r = string_util::replace_all(r, "_r_", lhs); @@ -8690,8 +8769,10 @@ auto i{0}; return r; } +#line 4801 "reflect.h2" + [[nodiscard]] auto autodiff_expression_handler::prepare_backprop(cpp2::impl::in rhs_b, cpp2::impl::in lhs) const& -> std::string { return prepare_backprop(rhs_b, lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix); } -#line 4781 "reflect.h2" +#line 4803 "reflect.h2" auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8703,14 +8784,14 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4792 "reflect.h2" +#line 4814 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b) & -> decltype(auto) { return gen_assignment(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr); } -#line 4794 "reflect.h2" +#line 4816 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_assignment(cpp2::impl::in lhs) & -> decltype(auto) { return gen_assignment(lhs, add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).fwd_suffix), add_suffix_if_not_wildcard(lhs, (*cpp2::impl::assert_not_null(ctx)).rws_suffix), primal_expr, fwd_expr, rws_expr); } -#line 4798 "reflect.h2" +#line 4820 "reflect.h2" auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type, cpp2::impl::in type_d, cpp2::impl::in type_b) & -> void{ CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs_d) + ": " + cpp2::to_string(type_d) + " = " + cpp2::to_string(rhs_d) + ";\n"); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + " = " + cpp2::to_string(rhs) + ";\n"); @@ -8723,25 +8804,24 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(lhs_b) + " = 0.0;\n"); CPP2_UFCS(add_reverse_backprop)(diff, prepare_backprop(rhs_b, lhs, lhs_d, lhs_b)); } -#line 4810 "reflect.h2" +#line 4832 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in rhs, cpp2::impl::in rhs_d, cpp2::impl::in rhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, rhs, rhs_d, rhs_b, type, CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type), CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)); } -#line 4812 "reflect.h2" +#line 4834 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in lhs_d, cpp2::impl::in lhs_b, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs_d, lhs_b, primal_expr, fwd_expr, rws_expr, type); } -#line 4814 "reflect.h2" +#line 4836 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::gen_declaration(cpp2::impl::in lhs, cpp2::impl::in type) & -> decltype(auto) { return gen_declaration(lhs, lhs + (*cpp2::impl::assert_not_null(ctx)).fwd_suffix, lhs + (*cpp2::impl::assert_not_null(ctx)).rws_suffix, type); } - autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(auto&& primal_, auto&& fwd_, auto&& rws_, auto&& active_) -requires (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) - : primal{ CPP2_FORWARD(primal_) } - , fwd{ CPP2_FORWARD(fwd_) } - , rws{ CPP2_FORWARD(rws_) } - , active{ CPP2_FORWARD(active_) }{} + autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(auto const& primal_, auto const& fwd_, auto const& rws_, auto const& active_) + : primal{ primal_ } + , fwd{ fwd_ } + , rws{ rws_ } + , active{ active_ }{} autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} -#line 4826 "reflect.h2" +#line 4848 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_list(cpp2::impl::in list) & -> std::vector{ std::vector args {}; for ( auto const& expr : CPP2_UFCS(get_expressions)(list) ) { @@ -8751,7 +8831,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} return args; } -#line 4835 "reflect.h2" +#line 4857 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_expression_term(auto const& term) & -> primal_fwd_rws_name{ if (CPP2_UFCS(is_identifier)(term)) { auto primal {CPP2_UFCS(to_string)(term)}; @@ -8813,7 +8893,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} }} } -#line 4896 "reflect.h2" +#line 4918 "reflect.h2" auto autodiff_expression_handler::handle_function_call(cpp2::impl::in postfix, cpp2::impl::in has_return) & -> void{ auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -8821,7 +8901,7 @@ autodiff_expression_handler::primal_fwd_rws_name::primal_fwd_rws_name(){} { auto i{0}; -#line 4902 "reflect.h2" +#line 4924 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -8835,7 +8915,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 4914 "reflect.h2" +#line 4936 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -8860,7 +8940,7 @@ auto i{0}; { auto i{0}; -#line 4937 "reflect.h2" +#line 4959 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(is_id_expression)(term)) ) { cpp2::cpp2_default.report_violation(""); } @@ -8885,7 +8965,7 @@ auto i{0}; } while (false); i += 1; } } -#line 4960 "reflect.h2" +#line 4982 "reflect.h2" if (handle_special_function(object, object_d, object_b, function_name, args)) { return ; } @@ -9002,10 +9082,10 @@ auto i{0}; // TODO: Add function to list of functions/objects for differentiation for the no return case. } -#line 5076 "reflect.h2" +#line 5098 "reflect.h2" [[nodiscard]] auto autodiff_expression_handler::handle_special_function(cpp2::impl::in object, cpp2::impl::in object_d, cpp2::impl::in object_b, cpp2::impl::in function_name, cpp2::impl::in> args) & -> bool{ - auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, CPP2_UFCS(ssize)(args), !(CPP2_UFCS(empty)(object)))}; + auto r {CPP2_UFCS(lookup_special_function_handling)((*cpp2::impl::assert_not_null(ctx)), function_name, cpp2::unchecked_narrow(CPP2_UFCS(ssize)(args)), !(CPP2_UFCS(empty)(object)))}; if (!(r.m)) { return false; // No match @@ -9030,7 +9110,7 @@ auto i{0}; { auto i{1}; -#line 5102 "reflect.h2" +#line 5124 "reflect.h2" for ( auto const& arg : args ) { code_primal = string_util::replace_all(code_primal, "_a" + cpp2::to_string(i) + "_", arg.primal); code_primal = string_util::replace_all(code_primal, "_ad" + cpp2::to_string(i) + "_", arg.fwd); @@ -9044,7 +9124,7 @@ auto i{1}; } } -#line 5114 "reflect.h2" +#line 5136 "reflect.h2" primal_expr = cpp2::move(code_primal); fwd_expr = cpp2::move(code_fwd); rws_expr = cpp2::move(code_rws); @@ -9052,62 +9132,62 @@ auto i{1}; return true; } -#line 5121 "reflect.h2" +#line 5143 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5125 "reflect.h2" +#line 5147 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Assign expressions are not yet handled."); } -#line 5129 "reflect.h2" +#line 5151 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled."); } -#line 5133 "reflect.h2" +#line 5155 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled."); } -#line 5137 "reflect.h2" +#line 5159 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled."); } -#line 5141 "reflect.h2" +#line 5163 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled."); } -#line 5145 "reflect.h2" +#line 5167 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled."); } -#line 5149 "reflect.h2" +#line 5171 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled."); } -#line 5153 "reflect.h2" +#line 5175 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled."); } -#line 5157 "reflect.h2" +#line 5179 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled."); } -#line 5161 "reflect.h2" +#line 5183 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled."); } -#line 5165 "reflect.h2" +#line 5187 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9139,7 +9219,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5196 "reflect.h2" +#line 5218 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9164,7 +9244,7 @@ auto i{1}; rws += "" + cpp2::to_string(var_a.rws) + " += " + cpp2::to_string(var_b.fwd) + "..mul(_rb_, " + cpp2::to_string(var_b.primal) + ", _r_);\n"; } if (var_b.active) { - if (!(CPP2_UFCS(empty)(fwd))) {fwd += " + "; } + //if !fwd.empty() { fwd += " + "; } //fwd += "(var_a.primal)$ * (var_b.fwd)$"; rws += "" + cpp2::to_string(var_b.rws) + " += " + cpp2::to_string(var_a.fwd) + "..mul(_rb_, " + cpp2::to_string(var_a.primal) + ", _r_);\n"; } @@ -9210,7 +9290,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5267 "reflect.h2" +#line 5289 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9227,12 +9307,12 @@ auto i{1}; } } -#line 5283 "reflect.h2" +#line 5305 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5287 "reflect.h2" +#line 5309 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9249,7 +9329,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5303 "reflect.h2" +#line 5325 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9258,7 +9338,7 @@ auto i{1}; { auto i{0}; -#line 5310 "reflect.h2" +#line 5332 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9273,7 +9353,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5323 "reflect.h2" +#line 5345 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9294,7 +9374,7 @@ auto i{0}; } } -#line 5343 "reflect.h2" +#line 5365 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9331,22 +9411,22 @@ auto i{0}; }}}} } -#line 5390 "reflect.h2" +#line 5415 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5393 "reflect.h2" +#line 5418 "reflect.h2" } -#line 5395 "reflect.h2" - auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params, cpp2::impl::in leave_open) & -> void{ +#line 5420 "reflect.h2" + [[nodiscard]] auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code{ + autodiff_diff_code r {ctx}; if (CPP2_UFCS(empty)(params)) { - return ; + return r; } - std::string fwd {"("}; for ( auto const& param : params ) { std::string name {CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(param))}; std::string type {CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))}; @@ -9358,6 +9438,7 @@ auto i{0}; std::string init {""}; std::string init_d {""}; + // TODO: Add handling for reverse expressions if (CPP2_UFCS(has_initializer)(CPP2_UFCS(get_declaration)(param))) { autodiff_expression_handler ad {ctx}; @@ -9369,33 +9450,30 @@ auto i{0}; } } -#line 5424 "reflect.h2" - fwd += "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "; +#line 5450 "reflect.h2" + CPP2_UFCS(add_forward)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(init) + ", "); + CPP2_UFCS(add_reverse_primal)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "); if (ada.active) { - fwd += "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + cpp2::to_string(cpp2::move(init_d)) + ", "; + CPP2_UFCS(add_forward)(r, "" + cpp2::to_string(cpp2::move(fwd_pass_style)) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + cpp2::to_string(cpp2::move(init_d)) + ", "); } CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(name), cpp2::move(type), cpp2::move(ada).active); } - if (!(leave_open)) { - fwd += ")"; - } - - diff += cpp2::move(fwd); + return r; } -#line 5439 "reflect.h2" +#line 5462 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5444 "reflect.h2" +#line 5467 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5449 "reflect.h2" +#line 5472 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9415,9 +9493,11 @@ auto i{0}; if (active) { auto fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; + auto rws_ad_type {CPP2_UFCS(get_rws_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)}; std::string prim_init {""}; std::string fwd_init {""}; + std::string rws_init {""}; if (CPP2_UFCS(has_initializer)(o)) { autodiff_expression_handler ad {ctx}; @@ -9426,14 +9506,23 @@ auto i{0}; prim_init = " = " + ad.primal_expr; fwd_init = " = " + ad.fwd_expr; + rws_init = " = ()"; // TODO: Proper initialization. + + if (ad.rws_expr != "()") { + CPP2_UFCS(add_reverse_backprop)(diff, CPP2_UFCS(prepare_backprop)(ad, ad.rws_expr, lhs)); + } if (type == "_" && cpp2::move(ad).fwd_expr == "()") { // Special handling for auto initialization from a literal. fwd_init = " = " + CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), "double") + "()"; } } - diff += "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"; - diff += "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"; + + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(cpp2::move(fwd_ad_type)) + cpp2::to_string(cpp2::move(fwd_init)) + ";\n"); + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(prim_init) + ";\n"); + + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " : " + cpp2::to_string(cpp2::move(rws_ad_type)) + cpp2::to_string(cpp2::move(rws_init)) + ";\n"); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(lhs) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(prim_init)) + ";\n"); } else { diff += "" + cpp2::to_string(lhs) + ": " + cpp2::to_string(type) + ""; @@ -9446,31 +9535,59 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5500 "reflect.h2" +#line 5534 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5505 "reflect.h2" +#line 5539 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5510 "reflect.h2" +#line 5544 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Remove this hack when statements like compound_statement can access their root statement. last_params = CPP2_UFCS(get_parameters)(stmt); base::traverse(stmt); } -#line 5517 "reflect.h2" +#line 5551 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - diff += "{\n"; - base::traverse(stmt); - diff += "}\n"; + autodiff_stmt_handler ad {ctx, mf}; + autodiff_stmt_handler ad_push_pop {ctx, mf}; + ad_push_pop.overwrite_push_pop = true; + + CPP2_UFCS(add_forward)(diff, "{\n"); + CPP2_UFCS(add_reverse_primal)(diff, "{\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "}\n"); + + for ( auto const& cur : CPP2_UFCS(get_statements)(stmt) ) { + CPP2_UFCS(pre_traverse)(ad, cur); + CPP2_UFCS(pre_traverse)(ad_push_pop, cur); + } + + for ( auto const& cur : ad.overwritten ) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cur)}; + CPP2_UFCS(add_reverse_primal)(diff, "cpp2::ad_stack::push<" + cpp2::to_string(cpp2::move(r).decl) + ">(" + cpp2::to_string(cur) + ");"); + } + + CPP2_UFCS(add_forward)(diff, ad.diff.fwd); + CPP2_UFCS(add_reverse_primal)(diff, ad.diff.rws_primal); + CPP2_UFCS(add_reverse_backprop)(diff, ad_push_pop.diff.rws_backprop); + CPP2_UFCS(add_reverse_backprop)(diff, cpp2::move(ad_push_pop).diff.rws_primal); + + for ( auto const& cur : cpp2::move(ad).overwritten ) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cur)}; + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(cur) + " = cpp2::ad_stack::pop<" + cpp2::to_string(cpp2::move(r).decl) + ">();"); + } + + CPP2_UFCS(add_forward)(diff, "}\n"); + CPP2_UFCS(add_reverse_primal)(diff, "}\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "{\n"); } -#line 5524 "reflect.h2" +#line 5586 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9487,13 +9604,33 @@ auto i{0}; } } -#line 5541 "reflect.h2" +#line 5602 "reflect.h2" + [[nodiscard]] auto autodiff_stmt_handler::reverse_next(cpp2::impl::in expr) const& -> std::string{ + if (CPP2_UFCS(contains)(expr, "+=")) { + return string_util::replace_all(expr, "+=", "-="); + } + else {if (CPP2_UFCS(contains)(expr, "-=")) { + return string_util::replace_all(expr, "-=", "+="); + }} + + CPP2_UFCS(error)(mf, "AD: Do not know how to reverse: " + cpp2::to_string(expr) + ""); + + return "Error"; + + } + +#line 5617 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ - if (!(CPP2_UFCS(empty)(last_params))) { - handle_stmt_parameters(last_params, CPP2_UFCS(is_for)(stmt)); + auto diff_params {handle_stmt_parameters(last_params)}; + + if (CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx))) && (CPP2_UFCS(is_while)(stmt) || CPP2_UFCS(is_do)(stmt))) { + CPP2_UFCS(error)(stmt, "AD: Alpha limitiation now reverse mode for while or do while."); } if (CPP2_UFCS(is_while)(stmt)) { + if (!(CPP2_UFCS(empty)(last_params))) { + CPP2_UFCS(add_forward)(diff, "(" + cpp2::move(diff_params).fwd + ")"); + } // TODO: Assumption is here that nothing is in the condition diff += "while " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_do_while_condition)(stmt))) + " "; if (CPP2_UFCS(has_next)(stmt)) { @@ -9504,6 +9641,10 @@ auto i{0}; pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); } else {if (CPP2_UFCS(is_do)(stmt)) { + if (!(CPP2_UFCS(empty)(last_params))) { + CPP2_UFCS(add_forward)(diff, "(" + cpp2::move(diff_params).fwd + ")"); + } + // TODO: Assumption is here that nothing is in the condition diff += "do "; pre_traverse(CPP2_UFCS(get_do_while_body)(stmt)); @@ -9524,27 +9665,59 @@ auto i{0}; auto param {CPP2_UFCS(get_for_parameter)(stmt)}; auto param_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; auto param_decl {CPP2_UFCS(get_declaration)(cpp2::move(param))}; - if (CPP2_UFCS(empty)(last_params)) { - diff += "("; // Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + + std::string rws {"("}; + std::string rws_restore {""}; + CPP2_UFCS(add_forward)(diff, "(");// Open statment parameter scope. If the loop has parameters, they are alrady handled and the brace is left open. + CPP2_UFCS(add_reverse_primal)(diff, "{\n"); + if (!(CPP2_UFCS(empty)(last_params))) { + for ( auto const& cur : last_params ) { + if (CPP2_UFCS(has_initializer)(CPP2_UFCS(get_declaration)(cur))) { + // TODO: Handle no type and no initializer. Handle passing style. + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ": " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + " = " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_initializer)(CPP2_UFCS(get_declaration)(cur)))) + ";\n"); + rws_restore += "cpp2::ad_stack::push<" + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + ">(" + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ");\n"; + rws += "" + cpp2::to_string(to_string_view(CPP2_UFCS(get_passing_style)(cur))) + " " + cpp2::to_string(CPP2_UFCS(name)(CPP2_UFCS(get_declaration)(cur))) + ": " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + " = cpp2::ad_stack::pop<" + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(cur))) + ">(), "; + } + } + CPP2_UFCS(add_forward)(diff, cpp2::move(diff_params).fwd); } - diff += "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"; - diff += "for " + cpp2::to_string(cpp2::move(range)) + " next ("; + CPP2_UFCS(add_forward)(diff, "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ".begin())\n"); + CPP2_UFCS(add_forward)(diff, "for " + cpp2::to_string(range) + " next ("); + + rws += "copy " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter := " + cpp2::to_string(range) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + ".rbegin())\n"; + rws += "for std::ranges::reverse_view(" + cpp2::to_string(range) + ") next ("; + CPP2_UFCS(add_reverse_primal)(diff, "for " + cpp2::to_string(cpp2::move(range)) + " next ("); if (CPP2_UFCS(has_next)(stmt)) { // TODO: Assumption is here that nothing is in the next expression - diff += "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "); + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt))) + ", "); + rws += "" + cpp2::to_string(reverse_next(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt)))) + ", "; } - diff += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter++"; - diff += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; - diff += "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "_d_iter*)"; + CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter++"); + CPP2_UFCS(add_forward)(diff, ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"); + rws += "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter++"; + rws += ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ") {\n"; + rws += "(inout " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + " := " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).rws_suffix) + "_iter*)\n"; + + CPP2_UFCS(add_reverse_primal)(diff, ") do (" + cpp2::to_string(param_style) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + ")"); + CPP2_UFCS(add_forward)(diff, "(" + cpp2::to_string(cpp2::move(param_style)) + " " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ": " + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + " = " + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + "_iter*)"); CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(param_decl)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(param_decl)) + "", true);// TODO: Handle loop/compound context variable declarations. + CPP2_UFCS(add_reverse_backprop)(diff, "}\n"); pre_traverse(CPP2_UFCS(get_for_body)(stmt)); - diff += "}\n"; + CPP2_UFCS(add_forward)(diff, "}\n"); + + if (CPP2_UFCS(has_next)(stmt)) { + CPP2_UFCS(add_reverse_primal)(diff, "" + cpp2::to_string(reverse_next(CPP2_UFCS(to_string)(CPP2_UFCS(get_next_expression)(stmt)))) + ";\n"); + } + CPP2_UFCS(add_reverse_primal)(diff, cpp2::move(rws_restore)); + CPP2_UFCS(add_reverse_primal)(diff, "}\n"); + CPP2_UFCS(add_reverse_backprop)(diff, cpp2::move(rws)); }} } -#line 5598 "reflect.h2" +#line 5715 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9556,12 +9729,12 @@ auto i{0}; } } -#line 5609 "reflect.h2" +#line 5726 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5613 "reflect.h2" +#line 5730 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9578,8 +9751,34 @@ auto i{0}; autodiff_expression_handler h {ctx}; CPP2_UFCS(pre_traverse)(h, CPP2_UFCS(get_term)(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(assignment_terms), 1))); - CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, cpp2::move(h_lhs).rws_expr); - append(cpp2::move(h)); + + auto is_overwrite {CPP2_UFCS(contains)(h.primal_expr, h_lhs.primal_expr)}; + if (overwrite_push_pop && is_overwrite) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), h_lhs.primal_expr)}; + CPP2_UFCS(add_reverse_primal)(diff, "cpp2::ad_stack::push<" + cpp2::to_string(cpp2::move(r).decl) + ">(" + cpp2::to_string(h_lhs.primal_expr) + ");"); + } + + if (is_overwrite && CPP2_UFCS(is_reverse)((*cpp2::impl::assert_not_null(ctx)))) { + auto t_b {CPP2_UFCS(gen_temporary)((*cpp2::impl::assert_not_null(ctx))) + (*cpp2::impl::assert_not_null(ctx)).rws_suffix}; + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, t_b); + append(cpp2::move(h)); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(h_lhs.rws_expr) + " = 0.0;\n"); + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(cpp2::move(t_b)) + " := " + cpp2::to_string(h_lhs.rws_expr) + ";\n"); + } + else { + CPP2_UFCS(gen_assignment)(h, h_lhs.primal_expr, h_lhs.fwd_expr, h_lhs.rws_expr); + append(cpp2::move(h)); + } + + if (overwrite_push_pop && is_overwrite) { + auto r {CPP2_UFCS(lookup_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), h_lhs.primal_expr)}; + CPP2_UFCS(add_reverse_backprop)(diff, "" + cpp2::to_string(h_lhs.primal_expr) + " = cpp2::ad_stack::pop<" + cpp2::to_string(cpp2::move(r).decl) + ">();"); + } + + // Simple overwrite check + if (cpp2::move(is_overwrite)) { + CPP2_UFCS(push_back)(overwritten, cpp2::move(h_lhs).primal_expr); + } } else { CPP2_UFCS(add_forward)(diff, CPP2_UFCS(to_string)(binexpr) + ";\n"); @@ -9587,73 +9786,73 @@ auto i{0}; } } -#line 5638 "reflect.h2" +#line 5781 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5642 "reflect.h2" +#line 5785 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5646 "reflect.h2" +#line 5789 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5650 "reflect.h2" +#line 5793 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5654 "reflect.h2" +#line 5797 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5658 "reflect.h2" +#line 5801 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5662 "reflect.h2" +#line 5805 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5666 "reflect.h2" +#line 5809 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5670 "reflect.h2" +#line 5813 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5674 "reflect.h2" +#line 5817 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5678 "reflect.h2" +#line 5821 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5682 "reflect.h2" +#line 5825 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5686 "reflect.h2" +#line 5829 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5691 "reflect.h2" +#line 5834 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9662,7 +9861,7 @@ auto i{0}; { auto i{0}; -#line 5698 "reflect.h2" +#line 5841 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9677,7 +9876,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5711 "reflect.h2" +#line 5854 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9690,27 +9889,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5723 "reflect.h2" +#line 5866 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5740 "reflect.h2" +#line 5883 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5743 "reflect.h2" +#line 5886 "reflect.h2" } -#line 5745 "reflect.h2" - auto autodiff_declaration_handler::traverse(cpp2::impl::in decl) -> void{ - base::traverse(decl); +#line 5888 "reflect.h2" + auto autodiff_declaration_handler::traverse(cpp2::impl::in decl_) -> void{ + base::traverse(decl_); } -#line 5750 "reflect.h2" +#line 5893 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -9817,7 +10016,7 @@ auto i{0}; auto type {CPP2_UFCS(get_declaration)(param).type()}; auto fwd_pass_style {to_string_view(CPP2_UFCS(get_passing_style)(param))}; - auto rws_pass_style {to_string_view(CPP2_UFCS(get_reverse_passing_style)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(get_passing_style)(param)))}; + //rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(CPP2_UFCS(type)(CPP2_UFCS(get_declaration)(param))) + " = 0.0, "); CPP2_UFCS(add_forward)(diff, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + " : " + cpp2::to_string(CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), type)) + " = 0.0, "); @@ -9840,10 +10039,10 @@ auto i{0}; return ; } -#line 5880 "reflect.h2" +#line 6023 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 5883 "reflect.h2" +#line 6026 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -9868,7 +10067,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 5908 "reflect.h2" +#line 6051 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -9896,7 +10095,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 5936 "reflect.h2" +#line 6079 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -9920,17 +10119,17 @@ auto i{0}; } } -#line 5960 "reflect.h2" +#line 6103 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5965 "reflect.h2" +#line 6108 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 5971 "reflect.h2" +#line 6114 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -9974,7 +10173,7 @@ auto autodiff(meta::type_declaration& t) -> void return ; } - autodiff_context ad_ctx {order, cpp2::move(reverse)}; + autodiff_context ad_ctx {order, reverse}; ad_ctx.fwd_suffix = cpp2::move(suffix); ad_ctx.rws_suffix = cpp2::move(rws_suffix); @@ -10009,6 +10208,9 @@ auto autodiff(meta::type_declaration& t) -> void if (1 != cpp2::move(order)) { CPP2_UFCS(add_runtime_support_include)(t, "cpp2taylor.h"); } + if (cpp2::move(reverse)) { + CPP2_UFCS(add_runtime_support_include)(t, "cpp2ad_stack.h"); + } CPP2_UFCS(finish)(ad_ctx); @@ -10106,7 +10308,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 6056 "reflect.h2" +#line 6202 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -10122,11 +10324,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 6072 "reflect.h2" +#line 6218 "reflect.h2" // Possible modifiers for a regular expression. // -#line 6076 "reflect.h2" +#line 6222 "reflect.h2" // mod: i // mod: m // mod: s @@ -10134,116 +10336,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 6085 "reflect.h2" +#line 6231 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 6094 "reflect.h2" +#line 6240 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 6096 "reflect.h2" +#line 6242 "reflect.h2" } -#line 6098 "reflect.h2" +#line 6244 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 6100 "reflect.h2" +#line 6246 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 6106 "reflect.h2" +#line 6252 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 6107 "reflect.h2" +#line 6253 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 6108 "reflect.h2" +#line 6254 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 6123 "reflect.h2" +#line 6269 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 6126 "reflect.h2" +#line 6272 "reflect.h2" } -#line 6128 "reflect.h2" +#line 6274 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 6132 "reflect.h2" +#line 6278 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6144 "reflect.h2" +#line 6290 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6147 "reflect.h2" +#line 6293 "reflect.h2" } -#line 6149 "reflect.h2" +#line 6295 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6153 "reflect.h2" +#line 6299 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6163 "reflect.h2" +#line 6309 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6165 "reflect.h2" +#line 6311 "reflect.h2" } -#line 6167 "reflect.h2" +#line 6313 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6171 "reflect.h2" +#line 6317 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6183 "reflect.h2" +#line 6329 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6186 "reflect.h2" +#line 6332 "reflect.h2" } -#line 6188 "reflect.h2" +#line 6334 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6194 "reflect.h2" +#line 6340 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6200 "reflect.h2" +#line 6346 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10252,7 +10454,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6208 "reflect.h2" +#line 6354 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10268,7 +10470,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6236 "reflect.h2" +#line 6382 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10276,14 +10478,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6244 "reflect.h2" +#line 6390 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6251 "reflect.h2" +#line 6397 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10295,15 +10497,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6263 "reflect.h2" +#line 6409 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6268 "reflect.h2" +#line 6414 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6272 "reflect.h2" +#line 6418 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10324,7 +10526,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6298 "reflect.h2" +#line 6444 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10333,20 +10535,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6307 "reflect.h2" +#line 6453 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6313 "reflect.h2" +#line 6459 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6320 "reflect.h2" +#line 6466 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10361,16 +10563,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6350 "reflect.h2" +#line 6496 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6354 "reflect.h2" +#line 6500 "reflect.h2" } -#line 6360 "reflect.h2" +#line 6506 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10380,7 +10582,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6370 "reflect.h2" +#line 6516 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10388,17 +10590,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6377 "reflect.h2" +#line 6523 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6381 "reflect.h2" +#line 6527 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6388 "reflect.h2" +#line 6534 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10408,7 +10610,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6397 "reflect.h2" +#line 6543 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10416,24 +10618,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6404 "reflect.h2" +#line 6550 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6412 "reflect.h2" +#line 6558 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6416 "reflect.h2" +#line 6562 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6420 "reflect.h2" +#line 6566 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10445,22 +10647,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6431 "reflect.h2" +#line 6577 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6437 "reflect.h2" +#line 6583 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6441 "reflect.h2" +#line 6587 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6445 "reflect.h2" +#line 6591 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10468,7 +10670,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6452 "reflect.h2" +#line 6598 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10480,10 +10682,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6465 "reflect.h2" +#line 6611 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6468 "reflect.h2" +#line 6614 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10523,7 +10725,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6508 "reflect.h2" +#line 6654 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10535,14 +10737,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6519 "reflect.h2" +#line 6665 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6520 "reflect.h2" +#line 6666 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6521 "reflect.h2" +#line 6667 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6523 "reflect.h2" +#line 6669 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10552,10 +10754,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6532 "reflect.h2" +#line 6678 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6534 "reflect.h2" +#line 6680 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10577,14 +10779,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6555 "reflect.h2" +#line 6701 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6556 "reflect.h2" +#line 6702 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6557 "reflect.h2" +#line 6703 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6559 "reflect.h2" +#line 6705 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10598,7 +10800,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6572 "reflect.h2" +#line 6718 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10620,7 +10822,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6593 "reflect.h2" +#line 6739 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10631,12 +10833,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6603 "reflect.h2" +#line 6749 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6604 "reflect.h2" +#line 6750 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6609 "reflect.h2" +#line 6755 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10691,7 +10893,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6663 "reflect.h2" +#line 6809 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10731,7 +10933,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6702 "reflect.h2" +#line 6848 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10747,21 +10949,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6719 "reflect.h2" +#line 6865 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6720 "reflect.h2" +#line 6866 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6721 "reflect.h2" +#line 6867 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6723 "reflect.h2" +#line 6869 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6738 "reflect.h2" +#line 6884 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10769,7 +10971,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6745 "reflect.h2" +#line 6891 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10779,22 +10981,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6763 "reflect.h2" +#line 6909 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6768 "reflect.h2" +#line 6914 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6774 "reflect.h2" +#line 6920 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6780 "reflect.h2" +#line 6926 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -10803,7 +11005,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6788 "reflect.h2" +#line 6934 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -10815,7 +11017,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6799 "reflect.h2" +#line 6945 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -10823,7 +11025,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6806 "reflect.h2" +#line 6952 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -10844,7 +11046,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6827 "reflect.h2" +#line 6973 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -10854,7 +11056,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6837 "reflect.h2" +#line 6983 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -10877,33 +11079,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6861 "reflect.h2" +#line 7007 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6867 "reflect.h2" +#line 7013 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 6871 "reflect.h2" +#line 7017 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6877 "reflect.h2" +#line 7023 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 6885 "reflect.h2" +#line 7031 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -10912,7 +11114,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 6893 "reflect.h2" +#line 7039 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -10921,22 +11123,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 6903 "reflect.h2" +#line 7049 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 6907 "reflect.h2" +#line 7053 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 6911 "reflect.h2" +#line 7057 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 6915 "reflect.h2" +#line 7061 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -10960,18 +11162,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 6940 "reflect.h2" +#line 7086 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 6955 "reflect.h2" +#line 7101 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 6957 "reflect.h2" +#line 7103 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -10982,15 +11184,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 6972 "reflect.h2" +#line 7118 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 6975 "reflect.h2" +#line 7121 "reflect.h2" } -#line 6977 "reflect.h2" +#line 7123 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -11008,7 +11210,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 6994 "reflect.h2" +#line 7140 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -11016,7 +11218,7 @@ generation_function_context::generation_function_context(){} } } -#line 7001 "reflect.h2" +#line 7147 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -11030,7 +11232,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7014 "reflect.h2" +#line 7160 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -11046,14 +11248,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 7035 "reflect.h2" +#line 7181 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 7037 "reflect.h2" +#line 7183 "reflect.h2" } -#line 7039 "reflect.h2" +#line 7185 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -11062,11 +11264,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 7054 "reflect.h2" +#line 7200 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 7056 "reflect.h2" +#line 7202 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -11074,7 +11276,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7063 "reflect.h2" +#line 7209 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11083,37 +11285,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7071 "reflect.h2" +#line 7217 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 7085 "reflect.h2" +#line 7231 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7089 "reflect.h2" +#line 7235 "reflect.h2" } -#line 7091 "reflect.h2" +#line 7237 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7095 "reflect.h2" +#line 7241 "reflect.h2" } -#line 7097 "reflect.h2" +#line 7243 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 7101 "reflect.h2" +#line 7247 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -11122,14 +11324,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 7107 "reflect.h2" +#line 7253 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 7112 "reflect.h2" +#line 7258 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -11142,7 +11344,7 @@ size_t i{0}; } } -#line 7124 "reflect.h2" +#line 7270 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11164,7 +11366,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7145 "reflect.h2" +#line 7291 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11183,7 +11385,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7163 "reflect.h2" +#line 7309 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11199,14 +11401,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7178 "reflect.h2" +#line 7324 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7184 "reflect.h2" +#line 7330 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11214,19 +11416,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7201 "reflect.h2" +#line 7347 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7202 "reflect.h2" +#line 7348 "reflect.h2" { -#line 7207 "reflect.h2" +#line 7353 "reflect.h2" } -#line 7210 "reflect.h2" +#line 7356 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11352,7 +11554,7 @@ size_t i{0}; ); } -#line 7335 "reflect.h2" +#line 7481 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11362,13 +11564,13 @@ size_t i{0}; ); } -#line 7344 "reflect.h2" +#line 7490 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7349 "reflect.h2" +#line 7495 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11379,12 +11581,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7361 "reflect.h2" +#line 7507 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7366 "reflect.h2" +#line 7512 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11418,7 +11620,7 @@ size_t i{0}; } -#line 7402 "reflect.h2" +#line 7548 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11427,19 +11629,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7425 "reflect.h2" +#line 7571 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7426 "reflect.h2" +#line 7572 "reflect.h2" { -#line 7431 "reflect.h2" +#line 7577 "reflect.h2" } -#line 7433 "reflect.h2" +#line 7579 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11541,19 +11743,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7534 "reflect.h2" +#line 7680 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7538 "reflect.h2" +#line 7684 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7562 "reflect.h2" +#line 7708 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11572,7 +11774,7 @@ size_t i{0}; return r; } -#line 7580 "reflect.h2" +#line 7726 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11587,7 +11789,7 @@ size_t i{0}; return r; } -#line 7594 "reflect.h2" +#line 7740 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11747,7 +11949,7 @@ size_t i{0}; } } -#line 7753 "reflect.h2" +#line 7899 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11756,7 +11958,7 @@ size_t i{0}; return r; } -#line 7761 "reflect.h2" +#line 7907 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11775,7 +11977,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7779 "reflect.h2" +#line 7925 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -11807,7 +12009,7 @@ size_t i{0}; } } -#line 7810 "reflect.h2" +#line 7956 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -11818,7 +12020,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7822 "reflect.h2" +#line 7968 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -11857,7 +12059,7 @@ size_t i{0}; return r; } -#line 7863 "reflect.h2" +#line 8009 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -11875,7 +12077,7 @@ size_t i{0}; }} } -#line 7883 "reflect.h2" +#line 8029 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -11889,16 +12091,16 @@ size_t i{0}; } } -#line 7909 "reflect.h2" +#line 8055 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 7912 "reflect.h2" +#line 8058 "reflect.h2" } -#line 7914 "reflect.h2" +#line 8060 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -11910,7 +12112,7 @@ size_t i{0}; } } -#line 7925 "reflect.h2" +#line 8071 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -11918,14 +12120,14 @@ size_t i{0}; return r; } -#line 7932 "reflect.h2" +#line 8078 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 7940 "reflect.h2" +#line 8086 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11951,7 +12153,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 7968 "reflect.h2" +#line 8114 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -11977,11 +12179,11 @@ size_t i{0}; return r; } -#line 8005 "reflect.h2" +#line 8151 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 8007 "reflect.h2" +#line 8153 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12055,7 +12257,7 @@ size_t i{0}; return nullptr; } -#line 8080 "reflect.h2" +#line 8226 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -12068,7 +12270,7 @@ size_t i{0}; }} } -#line 8092 "reflect.h2" +#line 8238 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -12082,7 +12284,7 @@ size_t i{0}; }} } -#line 8105 "reflect.h2" +#line 8251 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -12102,7 +12304,7 @@ size_t i{0}; return r; } -#line 8124 "reflect.h2" +#line 8270 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -12113,7 +12315,7 @@ size_t i{0}; return r; } -#line 8134 "reflect.h2" +#line 8280 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -12125,14 +12327,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8145 "reflect.h2" +#line 8291 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8157 "reflect.h2" +#line 8303 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12156,7 +12358,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8181 "reflect.h2" +#line 8327 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12166,7 +12368,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8193 "reflect.h2" +#line 8339 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12182,7 +12384,7 @@ size_t i{0}; } } -#line 8213 "reflect.h2" +#line 8359 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12200,15 +12402,15 @@ size_t i{0}; }} } -#line 8249 "reflect.h2" +#line 8395 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8252 "reflect.h2" +#line 8398 "reflect.h2" } -#line 8254 "reflect.h2" +#line 8400 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12244,7 +12446,7 @@ size_t i{0}; return source; } -#line 8289 "reflect.h2" +#line 8435 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12260,7 +12462,7 @@ size_t i{0}; } } -#line 8305 "reflect.h2" +#line 8451 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12269,7 +12471,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12324,7 +12526,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8374 "reflect.h2" +#line 8520 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12452,7 +12654,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8502 "reflect.h2" +#line 8648 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 50080edc0..d7e5196e1 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -231,7 +231,7 @@ reflection_base: @polymorphic_base @copy_constructible type = print: (this) -> std::string = n*.pretty_print_visualize(0); is_same: (this, o: reflection_base) -> bool = n == o.n; // Test pointers - is_same: (this, o: reflection_base) -> bool = false; // Different types => false + is_same: (this, _: reflection_base) -> bool = false; // Different types => false } @@ -4103,7 +4103,7 @@ sample_traverser: (idexpr: meta::id_expression, indent: i32) = //----------------------------------------------------------------------- // -// autodiff - stub +// autodiff // autodiff_special_func: type = { @@ -4150,7 +4150,7 @@ autodiff_special_func: type = { } } -autodiff_declared_variable: type = { +autodiff_declared_variable: @copy_constructible type = { public name : std::string = ""; public decl : std::string = ""; // TODO: Maybe use variant here. public is_active: bool = false; @@ -4193,8 +4193,13 @@ autodiff_declaration_stack_item: @copy_constructible type = { } lookup_variable_declaration: (this, decl_name: std::string) -> (found: bool = false, r: autodiff_declared_variable = ()) = { - for std::ranges::views::reverse(declared_variables_stack) do (cur_context) { - for cur_context do (cur) { + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + (copy cur_context := declared_variables_stack.rbegin()) + while cur_context != declared_variables_stack.rend() + next cur_context++ + { + for cur_context* do (cur) { if cur.name == decl_name { found = true; r = cur; @@ -4406,12 +4411,16 @@ autodiff_context: type = { } lookup_declaration: (inout this, decl_name: std::string) -> (r : std::vector = ()) = { - for std::ranges::views::reverse(declaration_stack) do (cur) { - - cur_full_name : std::string = cur.full_name + "::" + decl_name; + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + (copy cur := declaration_stack.rbegin()) + while cur != declaration_stack.rend() + next cur++ + { + cur_full_name : std::string = cur*.full_name + "::" + decl_name; ele := declaration_map.find(cur_full_name); if ele == declaration_map.end() { - ele = declaration_map.insert_or_assign(cur_full_name, cur.lookup_declaration(decl_name)).first; + ele = declaration_map.insert_or_assign(cur_full_name, cur*.lookup_declaration(decl_name)).first; } if !ele*.second.empty() { @@ -4433,8 +4442,13 @@ autodiff_context: type = { return autodiff_declared_variable(name, "_", false, false); } - for std::ranges::views::reverse(declaration_stack) do (cur_context) { - r := cur_context.lookup_variable_declaration(name); + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + (copy cur_context := declaration_stack.rbegin()) + while cur_context != declaration_stack.rend() + next cur_context++ + { + r := cur_context*.lookup_variable_declaration(name); if r.found { return r.r; } @@ -4512,10 +4526,16 @@ autodiff_context: type = { t_parent := t.get_parent(); found := false; - for std::ranges::views::reverse(declaration_stack) do (inout cur) { - if t_parent.is_same(cur.decl) { - if !is_in_list(t, cur.diff_request) { - cur.diff_request.push_back(t); + + // Note: Not using "for std::ranges::views::reverse(...)" because + // that does not work correctly in Clang 12 + older libstdc++ + (copy cur := declaration_stack.rbegin()) + while cur != declaration_stack.rend() + next cur++ + { + if t_parent.is_same(cur*.decl) { + if !is_in_list(t, cur*.diff_request) { + cur*.diff_request.push_back(t); } found = true; @@ -4818,7 +4838,7 @@ autodiff_expression_handler: type = { - primal_fwd_rws_name: @struct type = { + primal_fwd_rws_name: @struct type = { primal: std::string = ""; fwd : std::string = ""; rws : std::string = ""; @@ -5077,7 +5097,7 @@ autodiff_expression_handler: type = { handle_special_function: (inout this, object: std::string, object_d: std::string, object_b: std::string, function_name: std::string, args: std::vector) -> bool = { - r := ctx*.lookup_special_function_handling(function_name, args.ssize(), !object.empty()); + r := ctx*.lookup_special_function_handling(function_name, unchecked_narrow(args.ssize()), !object.empty()); if !r.m { return false; // No match @@ -5219,7 +5239,7 @@ autodiff_expression_handler: type = { rws += "(var_a.rws)$ += (var_b.fwd)$..mul(_rb_, (var_b.primal)$, _r_);\n"; } if var_b.active { - if !fwd.empty() { fwd += " + "; } + //if !fwd.empty() { fwd += " + "; } //fwd += "(var_a.primal)$ * (var_b.fwd)$"; rws += "(var_b.rws)$ += (var_a.fwd)$..mul(_rb_, (var_a.primal)$, _r_);\n"; } @@ -5865,8 +5885,8 @@ autodiff_declaration_handler: type = { decl = decl_; } - traverse: (override inout this, decl: meta::declaration) = { - base::traverse(decl); + traverse: (override inout this, decl_: meta::declaration) = { + base::traverse(decl_); } @@ -5976,7 +5996,7 @@ autodiff_declaration_handler: type = { type := param.get_declaration().type(); fwd_pass_style := to_string_view(param.get_passing_style()); - rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); + //rws_pass_style := to_string_view(ctx*.get_reverse_passing_style(param.get_passing_style())); diff.add_forward("(fwd_pass_style)$ (name)$ : (param.get_declaration().type())$ = 0.0, "); diff.add_forward("(fwd_pass_style)$ (name)$(ctx*.fwd_suffix)$ : (ctx*.get_fwd_ad_type(type))$ = 0.0, "); From ece0c9bd06917e715bc3e7548955deace6a60a44 Mon Sep 17 00:00:00 2001 From: Max Sagebaum Date: Mon, 8 Sep 2025 23:02:43 +0200 Subject: [PATCH 53/54] Bugfix for passive variables in addition or subtraction statements. --- source/reflect.h | 981 +++++++++++++++++++++++----------------------- source/reflect.h2 | 19 +- 2 files changed, 511 insertions(+), 489 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 979b6c095..b6a74a96c 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -137,83 +137,83 @@ class autodiff_handler_base; class autodiff_expression_handler; -#line 5402 "reflect.h2" +#line 5413 "reflect.h2" class autodiff_stmt_handler; -#line 5872 "reflect.h2" +#line 5883 "reflect.h2" class autodiff_declaration_handler; -#line 6220 "reflect.h2" +#line 6231 "reflect.h2" class expression_flags; -#line 6236 "reflect.h2" +#line 6247 "reflect.h2" class regex_token; -#line 6263 "reflect.h2" +#line 6274 "reflect.h2" class regex_token_check; -#line 6284 "reflect.h2" +#line 6295 "reflect.h2" class regex_token_code; -#line 6305 "reflect.h2" +#line 6316 "reflect.h2" class regex_token_empty; -#line 6323 "reflect.h2" +#line 6334 "reflect.h2" class regex_token_list; -#line 6375 "reflect.h2" +#line 6386 "reflect.h2" class parse_context_group_state; -#line 6436 "reflect.h2" +#line 6447 "reflect.h2" class parse_context_branch_reset_state; -#line 6479 "reflect.h2" +#line 6490 "reflect.h2" class parse_context; -#line 6880 "reflect.h2" +#line 6891 "reflect.h2" class generation_function_context; -#line 6898 "reflect.h2" +#line 6909 "reflect.h2" class generation_context; -#line 7097 "reflect.h2" +#line 7108 "reflect.h2" class alternative_token; -#line 7112 "reflect.h2" +#line 7123 "reflect.h2" class alternative_token_gen; -#line 7177 "reflect.h2" +#line 7188 "reflect.h2" class any_token; -#line 7194 "reflect.h2" +#line 7205 "reflect.h2" class atomic_group_token; -#line 7224 "reflect.h2" +#line 7235 "reflect.h2" class char_token; -#line 7339 "reflect.h2" +#line 7350 "reflect.h2" class class_token; -#line 7563 "reflect.h2" +#line 7574 "reflect.h2" class group_ref_token; -#line 7700 "reflect.h2" +#line 7711 "reflect.h2" class group_token; -#line 8047 "reflect.h2" +#line 8058 "reflect.h2" class lookahead_lookbehind_token; -#line 8142 "reflect.h2" +#line 8153 "reflect.h2" class range_token; -#line 8299 "reflect.h2" +#line 8310 "reflect.h2" class special_range_token; -#line 8385 "reflect.h2" +#line 8396 "reflect.h2" template class regex_generator; -#line 8648 "reflect.h2" +#line 8659 "reflect.h2" } } @@ -2093,30 +2093,30 @@ public: primal_fwd_rws_name(); #line 5187 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5218 "reflect.h2" +#line 5229 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5305 "reflect.h2" +#line 5316 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5309 "reflect.h2" +#line 5320 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5325 "reflect.h2" +#line 5336 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5365 "reflect.h2" +#line 5376 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_expression_handler(autodiff_expression_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_expression_handler const&) -> void = delete; -#line 5400 "reflect.h2" +#line 5411 "reflect.h2" }; class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_base { -#line 5406 "reflect.h2" +#line 5417 "reflect.h2" public: using base = simple_traverser; private: meta::function_declaration mf; @@ -2128,102 +2128,102 @@ class autodiff_stmt_handler: public simple_traverser, public autodiff_handler_ba public: autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_); -#line 5420 "reflect.h2" +#line 5431 "reflect.h2" public: [[nodiscard]] auto handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code; -#line 5462 "reflect.h2" +#line 5473 "reflect.h2" public: auto traverse(cpp2::impl::in decl) -> void override; -#line 5467 "reflect.h2" +#line 5478 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 5472 "reflect.h2" +#line 5483 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 5534 "reflect.h2" +#line 5545 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5539 "reflect.h2" +#line 5550 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 5544 "reflect.h2" +#line 5555 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5551 "reflect.h2" +#line 5562 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5586 "reflect.h2" +#line 5597 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5602 "reflect.h2" +#line 5613 "reflect.h2" public: [[nodiscard]] auto reverse_next(cpp2::impl::in expr) const& -> std::string; -#line 5617 "reflect.h2" +#line 5628 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5715 "reflect.h2" +#line 5726 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; -#line 5726 "reflect.h2" +#line 5737 "reflect.h2" public: auto traverse(cpp2::impl::in expr) -> void override; -#line 5730 "reflect.h2" +#line 5741 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5781 "reflect.h2" +#line 5792 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5785 "reflect.h2" +#line 5796 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5789 "reflect.h2" +#line 5800 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5793 "reflect.h2" +#line 5804 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5797 "reflect.h2" +#line 5808 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5801 "reflect.h2" +#line 5812 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5805 "reflect.h2" +#line 5816 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5809 "reflect.h2" +#line 5820 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5813 "reflect.h2" +#line 5824 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5817 "reflect.h2" +#line 5828 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5821 "reflect.h2" +#line 5832 "reflect.h2" public: auto traverse(cpp2::impl::in binexpr) -> void override; -#line 5825 "reflect.h2" +#line 5836 "reflect.h2" public: auto traverse(cpp2::impl::in isas) -> void override; -#line 5829 "reflect.h2" +#line 5840 "reflect.h2" public: auto traverse(cpp2::impl::in prefix) -> void override; -#line 5834 "reflect.h2" +#line 5845 "reflect.h2" public: auto traverse(cpp2::impl::in postfix) -> void override; -#line 5866 "reflect.h2" +#line 5877 "reflect.h2" public: auto traverse(cpp2::impl::in primary) -> void override; public: autodiff_stmt_handler(autodiff_stmt_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_stmt_handler const&) -> void = delete; -#line 5870 "reflect.h2" +#line 5881 "reflect.h2" }; class autodiff_declaration_handler: public simple_traverser, public autodiff_handler_base { -#line 5876 "reflect.h2" +#line 5887 "reflect.h2" public: using base = simple_traverser; private: meta::type_or_namespace_declaration decl; @@ -2233,37 +2233,37 @@ class autodiff_declaration_handler: public simple_traverser, public autodiff_han public: autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_); -#line 5888 "reflect.h2" +#line 5899 "reflect.h2" public: auto traverse(cpp2::impl::in decl_) -> void override; -#line 5893 "reflect.h2" +#line 5904 "reflect.h2" public: auto traverse(cpp2::impl::in f) -> void override; -#line 6051 "reflect.h2" +#line 6062 "reflect.h2" public: auto traverse(cpp2::impl::in o) -> void override; -#line 6079 "reflect.h2" +#line 6090 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 6103 "reflect.h2" +#line 6114 "reflect.h2" public: auto traverse(cpp2::impl::in t) -> void override; -#line 6108 "reflect.h2" +#line 6119 "reflect.h2" public: auto traverse(cpp2::impl::in stmt) -> void override; public: autodiff_declaration_handler(autodiff_declaration_handler const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(autodiff_declaration_handler const&) -> void = delete; -#line 6111 "reflect.h2" +#line 6122 "reflect.h2" }; -#line 6114 "reflect.h2" +#line 6125 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void; -#line 6216 "reflect.h2" +#line 6227 "reflect.h2" using error_func = std::function x)>; -#line 6220 "reflect.h2" +#line 6231 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -2298,20 +2298,20 @@ public: [[nodiscard]] auto to_code() const& -> std::string; public: [[nodiscard]] static auto from_string(cpp2::impl::in s) -> expression_flags; public: [[nodiscard]] static auto from_code(cpp2::impl::in s) -> expression_flags; -#line 6228 "reflect.h2" +#line 6239 "reflect.h2" }; -#line 6236 "reflect.h2" +#line 6247 "reflect.h2" class regex_token { public: std::string string_rep; public: regex_token(cpp2::impl::in str); -#line 6244 "reflect.h2" +#line 6255 "reflect.h2" public: explicit regex_token(); -#line 6249 "reflect.h2" +#line 6260 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: [[nodiscard]] virtual auto reverse() const -> std::shared_ptr = 0; @@ -2323,103 +2323,103 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 6255 "reflect.h2" +#line 6266 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 6261 "reflect.h2" +#line 6272 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 6267 "reflect.h2" +#line 6278 "reflect.h2" private: std::string check; public: regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 6274 "reflect.h2" +#line 6285 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6278 "reflect.h2" +#line 6289 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_check() noexcept; public: regex_token_check(regex_token_check const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_check const&) -> void = delete; -#line 6279 "reflect.h2" +#line 6290 "reflect.h2" }; -#line 6282 "reflect.h2" +#line 6293 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 6288 "reflect.h2" +#line 6299 "reflect.h2" private: std::string code; public: regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 6295 "reflect.h2" +#line 6306 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6299 "reflect.h2" +#line 6310 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_code() noexcept; public: regex_token_code(regex_token_code const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_code const&) -> void = delete; -#line 6300 "reflect.h2" +#line 6311 "reflect.h2" }; -#line 6303 "reflect.h2" +#line 6314 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 6309 "reflect.h2" +#line 6320 "reflect.h2" public: regex_token_empty(cpp2::impl::in str); -#line 6313 "reflect.h2" +#line 6324 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; -#line 6317 "reflect.h2" +#line 6328 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_empty() noexcept; public: regex_token_empty(regex_token_empty const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token_empty const&) -> void = delete; -#line 6318 "reflect.h2" +#line 6329 "reflect.h2" }; -#line 6321 "reflect.h2" +#line 6332 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 6327 "reflect.h2" +#line 6338 "reflect.h2" public: token_vec tokens; public: regex_token_list(cpp2::impl::in t); -#line 6334 "reflect.h2" +#line 6345 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 6340 "reflect.h2" +#line 6351 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 6346 "reflect.h2" +#line 6357 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; -#line 6354 "reflect.h2" +#line 6365 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~regex_token_list() noexcept; @@ -2427,10 +2427,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 6366 "reflect.h2" +#line 6377 "reflect.h2" }; -#line 6369 "reflect.h2" +#line 6380 "reflect.h2" // // Parse and generation context. // @@ -2446,33 +2446,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 6389 "reflect.h2" +#line 6400 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 6396 "reflect.h2" +#line 6407 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6408 "reflect.h2" +#line 6419 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 6413 "reflect.h2" +#line 6424 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 6417 "reflect.h2" +#line 6428 "reflect.h2" // Apply optimizations to the matcher list. public: static auto post_process_list(token_vec& list) -> void; public: parse_context_group_state(auto const& cur_match_list_, auto const& alternate_match_lists_, auto const& modifiers_); public: parse_context_group_state(); -#line 6431 "reflect.h2" +#line 6442 "reflect.h2" }; -#line 6434 "reflect.h2" +#line 6445 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -2485,25 +2485,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 6452 "reflect.h2" +#line 6463 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 6458 "reflect.h2" +#line 6469 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 6465 "reflect.h2" +#line 6476 "reflect.h2" // Initialize for a branch reset group. public: auto set_active_reset(cpp2::impl::in restart) & -> void; public: parse_context_branch_reset_state(auto const& is_active_, auto const& cur_group_, auto const& max_group_, auto const& from_); public: parse_context_branch_reset_state(); -#line 6472 "reflect.h2" +#line 6483 "reflect.h2" }; -#line 6475 "reflect.h2" +#line 6486 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -2519,7 +2519,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 6491 "reflect.h2" +#line 6502 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -2527,64 +2527,64 @@ class parse_context public: parse_context(cpp2::impl::in r, auto const& e); -#line 6502 "reflect.h2" +#line 6513 "reflect.h2" // State management functions // // Returned group state needs to be stored and provided in `end_group`. public: [[nodiscard]] auto start_group() & -> parse_context_group_state; -#line 6515 "reflect.h2" +#line 6526 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 6523 "reflect.h2" +#line 6534 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 6527 "reflect.h2" +#line 6538 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 6531 "reflect.h2" +#line 6542 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 6543 "reflect.h2" +#line 6554 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 6550 "reflect.h2" +#line 6561 "reflect.h2" public: auto next_alternative() & -> void; -#line 6556 "reflect.h2" +#line 6567 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 6562 "reflect.h2" +#line 6573 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 6566 "reflect.h2" +#line 6577 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 6577 "reflect.h2" +#line 6588 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 6581 "reflect.h2" +#line 6592 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 6587 "reflect.h2" +#line 6598 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 6591 "reflect.h2" +#line 6602 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 6598 "reflect.h2" +#line 6609 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 6609 "reflect.h2" +#line 6620 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -2592,51 +2592,51 @@ class parse_context // Get the next token in the regex, skipping spaces according to the parameters. See `x` and `xx` modifiers. private: [[nodiscard]] auto get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t; -#line 6653 "reflect.h2" +#line 6664 "reflect.h2" // Return true if next token is available. private: [[nodiscard]] auto next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool; -#line 6665 "reflect.h2" +#line 6676 "reflect.h2" public: [[nodiscard]] auto next() & -> decltype(auto); public: [[nodiscard]] auto next_in_class() & -> decltype(auto); public: [[nodiscard]] auto next_no_skip() & -> decltype(auto); public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 6678 "reflect.h2" +#line 6689 "reflect.h2" public: [[nodiscard]] auto has_next() const& -> bool; private: [[nodiscard]] auto grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool; -#line 6701 "reflect.h2" +#line 6712 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto); public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 6718 "reflect.h2" +#line 6729 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 6739 "reflect.h2" +#line 6750 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 6749 "reflect.h2" +#line 6760 "reflect.h2" public: [[nodiscard]] auto peek() const& -> decltype(auto); public: [[nodiscard]] auto peek_in_class() const& -> decltype(auto); -#line 6753 "reflect.h2" +#line 6764 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 6809 "reflect.h2" +#line 6820 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 6848 "reflect.h2" +#line 6859 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 6863 "reflect.h2" +#line 6874 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> decltype(auto); @@ -2648,10 +2648,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 6874 "reflect.h2" +#line 6885 "reflect.h2" }; -#line 6877 "reflect.h2" +#line 6888 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -2661,16 +2661,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 6891 "reflect.h2" +#line 6902 "reflect.h2" public: auto remove_tabs(cpp2::impl::in c) & -> void; public: generation_function_context(auto const& code_, auto const& tabs_); public: generation_function_context(); -#line 6894 "reflect.h2" +#line 6905 "reflect.h2" }; -#line 6897 "reflect.h2" +#line 6908 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -2690,68 +2690,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 6919 "reflect.h2" +#line 6930 "reflect.h2" // Add check for token. The check needs to be a function call that returns a boolean. public: auto add_check(cpp2::impl::in check) & -> void; -#line 6925 "reflect.h2" +#line 6936 "reflect.h2" // Add a stateful check. The check needs to return a `match_return`. public: auto add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void; -#line 6934 "reflect.h2" +#line 6945 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 6945 "reflect.h2" +#line 6956 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 6952 "reflect.h2" +#line 6963 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 6972 "reflect.h2" +#line 6983 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 6982 "reflect.h2" +#line 6993 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 7005 "reflect.h2" +#line 7016 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 7013 "reflect.h2" +#line 7024 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 7017 "reflect.h2" +#line 7028 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 7023 "reflect.h2" +#line 7034 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 7029 "reflect.h2" +#line 7040 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 7039 "reflect.h2" +#line 7050 "reflect.h2" public: auto finish_context() & -> void; -#line 7047 "reflect.h2" +#line 7058 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 7053 "reflect.h2" +#line 7064 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 7057 "reflect.h2" +#line 7068 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 7061 "reflect.h2" +#line 7072 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 7085 "reflect.h2" +#line 7096 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -2759,7 +2759,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 7091 "reflect.h2" +#line 7102 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -2779,27 +2779,27 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 7110 "reflect.h2" +#line 7121 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 7116 "reflect.h2" +#line 7127 "reflect.h2" private: token_vec alternatives; public: alternative_token_gen(cpp2::impl::in a); -#line 7123 "reflect.h2" +#line 7134 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7140 "reflect.h2" +#line 7151 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 7147 "reflect.h2" +#line 7158 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; -#line 7160 "reflect.h2" +#line 7171 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; public: virtual ~alternative_token_gen() noexcept; @@ -2807,19 +2807,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 7172 "reflect.h2" +#line 7183 "reflect.h2" }; -#line 7175 "reflect.h2" +#line 7186 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 7181 "reflect.h2" +#line 7192 "reflect.h2" public: any_token(cpp2::impl::in single_line); -#line 7185 "reflect.h2" +#line 7196 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -2827,7 +2827,7 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 7190 "reflect.h2" +#line 7201 "reflect.h2" }; // Regex syntax: (?>) Example: a(?>bc|c)c @@ -2835,17 +2835,17 @@ class any_token class atomic_group_token : public regex_token { -#line 7198 "reflect.h2" +#line 7209 "reflect.h2" public: token_ptr inner_token {nullptr}; public: explicit atomic_group_token(); public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7209 "reflect.h2" +#line 7220 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7217 "reflect.h2" +#line 7228 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~atomic_group_token() noexcept; @@ -2853,7 +2853,7 @@ class atomic_group_token public: auto operator=(atomic_group_token const&) -> void = delete; -#line 7220 "reflect.h2" +#line 7231 "reflect.h2" }; // Regex syntax: a @@ -2861,34 +2861,34 @@ class atomic_group_token class char_token : public regex_token { -#line 7228 "reflect.h2" +#line 7239 "reflect.h2" private: std::string token; private: bool ignore_case; public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7237 "reflect.h2" +#line 7248 "reflect.h2" public: char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 7243 "reflect.h2" +#line 7254 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7247 "reflect.h2" +#line 7258 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7270 "reflect.h2" +#line 7281 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 7291 "reflect.h2" +#line 7302 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 7309 "reflect.h2" +#line 7320 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 7324 "reflect.h2" +#line 7335 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7330 "reflect.h2" +#line 7341 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -2896,33 +2896,33 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 7334 "reflect.h2" +#line 7345 "reflect.h2" }; -#line 7337 "reflect.h2" +#line 7348 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 7343 "reflect.h2" +#line 7354 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 7355 "reflect.h2" +#line 7366 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7481 "reflect.h2" +#line 7492 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7490 "reflect.h2" +#line 7501 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7495 "reflect.h2" +#line 7506 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -2930,20 +2930,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 7502 "reflect.h2" +#line 7513 "reflect.h2" }; -#line 7505 "reflect.h2" +#line 7516 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 7546 "reflect.h2" +#line 7557 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 7557 "reflect.h2" +#line 7568 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -2953,20 +2953,20 @@ class class_token class group_ref_token : public regex_token { -#line 7567 "reflect.h2" +#line 7578 "reflect.h2" private: int id; private: bool case_insensitive; private: bool reverse_eval; public: group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str); -#line 7579 "reflect.h2" +#line 7590 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7680 "reflect.h2" +#line 7691 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7684 "reflect.h2" +#line 7695 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -2974,10 +2974,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 7687 "reflect.h2" +#line 7698 "reflect.h2" }; -#line 7690 "reflect.h2" +#line 7701 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -2991,29 +2991,29 @@ class group_ref_token class group_token : public regex_token { -#line 7704 "reflect.h2" +#line 7715 "reflect.h2" private: int number {-1}; private: bool reverse_eval {false}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr; -#line 7726 "reflect.h2" +#line 7737 "reflect.h2" public: [[nodiscard]] static auto parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr; -#line 7740 "reflect.h2" +#line 7751 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 7899 "reflect.h2" +#line 7910 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 7907 "reflect.h2" +#line 7918 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string; -#line 7925 "reflect.h2" +#line 7936 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 7956 "reflect.h2" +#line 7967 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -3022,25 +3022,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 7963 "reflect.h2" +#line 7974 "reflect.h2" }; -#line 7966 "reflect.h2" +#line 7977 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 8007 "reflect.h2" +#line 8018 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 8027 "reflect.h2" +#line 8038 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 8043 "reflect.h2" +#line 8054 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -3048,20 +3048,20 @@ class group_token class lookahead_lookbehind_token : public regex_token { -#line 8051 "reflect.h2" +#line 8062 "reflect.h2" protected: bool lookahead; protected: bool positive; public: token_ptr inner {nullptr}; public: lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_); -#line 8060 "reflect.h2" +#line 8071 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8071 "reflect.h2" +#line 8082 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8078 "reflect.h2" +#line 8089 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_lookbehind_token() noexcept; @@ -3069,26 +3069,26 @@ class lookahead_lookbehind_token public: auto operator=(lookahead_lookbehind_token const&) -> void = delete; -#line 8081 "reflect.h2" +#line 8092 "reflect.h2" }; -#line 8084 "reflect.h2" +#line 8095 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 8112 "reflect.h2" +#line 8123 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 8140 "reflect.h2" +#line 8151 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 8146 "reflect.h2" +#line 8157 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -3098,22 +3098,22 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 8226 "reflect.h2" +#line 8237 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 8238 "reflect.h2" +#line 8249 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 8251 "reflect.h2" +#line 8262 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 8270 "reflect.h2" +#line 8281 "reflect.h2" public: [[nodiscard]] auto reverse() const -> token_ptr override; -#line 8280 "reflect.h2" +#line 8291 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 8291 "reflect.h2" +#line 8302 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -3121,16 +3121,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 8294 "reflect.h2" +#line 8305 "reflect.h2" }; -#line 8297 "reflect.h2" +#line 8308 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 8303 "reflect.h2" +#line 8314 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -3139,7 +3139,7 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 8333 "reflect.h2" +#line 8344 "reflect.h2" }; // Regex syntax: \G Example: \Gaa @@ -3148,14 +3148,14 @@ class special_range_token // [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr; -#line 8355 "reflect.h2" +#line 8366 "reflect.h2" // Regex syntax: \b or \B Example: \bword\b // // Matches the start end end of word boundaries. // [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr; -#line 8377 "reflect.h2" +#line 8388 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -3176,24 +3176,24 @@ template class regex_generator public: regex_generator(cpp2::impl::in r, Error_out const& e); -#line 8400 "reflect.h2" +#line 8411 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 8435 "reflect.h2" +#line 8446 "reflect.h2" private: auto extract_modifiers() & -> void; public: regex_generator(regex_generator const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_generator const&) -> void = delete; -#line 8449 "reflect.h2" +#line 8460 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 8461 "reflect.h2" +#line 8472 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 8516 "reflect.h2" +#line 8527 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -3204,7 +3204,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 8648 "reflect.h2" +#line 8659 "reflect.h2" } } @@ -9192,6 +9192,7 @@ auto i{1}; auto terms {CPP2_UFCS(get_terms)(binexpr)}; auto first {true}; + auto first_fwd {true}; std::string op {"+"}; std::string fwd {""}; std::string rws {""}; @@ -9199,15 +9200,25 @@ auto i{1}; for ( auto const& term : cpp2::move(terms) ) { if (!(first)) { op = CPP2_UFCS(to_string)(CPP2_UFCS(get_op)(term)); - fwd += " " + cpp2::to_string(op) + " "; primal += " " + cpp2::to_string(op) + " "; - } auto var {handle_expression_term(CPP2_UFCS(get_term)(term))}; if (var.active) { - fwd += var.fwd; + if (first_fwd) { + if (op == "-") {// Special handling for first fwd termn with minus + fwd += "-" + cpp2::to_string(var.fwd) + ""; + } + else { // Special handling for first fwd term with plus + fwd += var.fwd; + } + } + else { + fwd += "" + cpp2::to_string(op) + " " + cpp2::to_string(var.fwd) + ""; + } rws += "" + cpp2::to_string(var.rws) + " " + cpp2::to_string(op) + "= _rb_;\n"; + + first_fwd = false; } primal += cpp2::move(var).primal; @@ -9219,7 +9230,7 @@ auto i{1}; rws_expr = cpp2::move(rws); } -#line 5218 "reflect.h2" +#line 5229 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in binexpr) -> void{ auto terms {CPP2_UFCS(get_terms)(binexpr)}; @@ -9290,7 +9301,7 @@ auto i{1}; CPP2_UFCS(error)(binexpr, "unkown multiplicative operator '" + cpp2::to_string(cpp2::move(op)) + "'"); }} -#line 5289 "reflect.h2" +#line 5300 "reflect.h2" if (i + 1 == CPP2_UFCS(ssize)(terms)) { primal_expr = cpp2::move(primal); fwd_expr = cpp2::move(fwd); @@ -9307,12 +9318,12 @@ auto i{1}; } } -#line 5305 "reflect.h2" +#line 5316 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled."); } -#line 5309 "reflect.h2" +#line 5320 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in prefix) -> void { auto ops {CPP2_UFCS(get_ops)(prefix)}; @@ -9329,7 +9340,7 @@ auto i{1}; fwd_expr = CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(ops), 0) + cpp2::move(ad).fwd_expr; } -#line 5325 "reflect.h2" +#line 5336 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9338,7 +9349,7 @@ auto i{1}; { auto i{0}; -#line 5332 "reflect.h2" +#line 5343 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9353,7 +9364,7 @@ auto i{0}; } while (false); i += 1; } } -#line 5345 "reflect.h2" +#line 5356 "reflect.h2" if (cpp2::move(is_func)) { handle_function_call(postfix, true); } @@ -9374,7 +9385,7 @@ auto i{0}; } } -#line 5365 "reflect.h2" +#line 5376 "reflect.h2" auto autodiff_expression_handler::traverse(cpp2::impl::in primary) -> void { if (CPP2_UFCS(is_identifier)(primary)) { @@ -9411,16 +9422,16 @@ auto i{0}; }}}} } -#line 5415 "reflect.h2" +#line 5426 "reflect.h2" autodiff_stmt_handler::autodiff_stmt_handler(cpp2::impl::in ctx_, cpp2::impl::in mf_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , mf{ mf_ }{ -#line 5418 "reflect.h2" +#line 5429 "reflect.h2" } -#line 5420 "reflect.h2" +#line 5431 "reflect.h2" [[nodiscard]] auto autodiff_stmt_handler::handle_stmt_parameters(cpp2::impl::in> params) & -> autodiff_diff_code{ autodiff_diff_code r {ctx}; if (CPP2_UFCS(empty)(params)) { @@ -9450,7 +9461,7 @@ auto i{0}; } } -#line 5450 "reflect.h2" +#line 5461 "reflect.h2" CPP2_UFCS(add_forward)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(init) + ", "); CPP2_UFCS(add_reverse_primal)(r, "" + cpp2::to_string(fwd_pass_style) + " " + cpp2::to_string(name) + " : " + cpp2::to_string(type) + cpp2::to_string(cpp2::move(init)) + ", "); if (ada.active) { @@ -9463,17 +9474,17 @@ auto i{0}; return r; } -#line 5462 "reflect.h2" +#line 5473 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in decl) -> void{ base::traverse(decl); } -#line 5467 "reflect.h2" +#line 5478 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(error)(f, "AD: Do not know how to handle function_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(f)) + ""); } -#line 5472 "reflect.h2" +#line 5483 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in o) -> void{ std::string lhs {CPP2_UFCS(name)(o)}; auto type {o.type()}; @@ -9535,24 +9546,24 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), cpp2::move(lhs), cpp2::move(type), cpp2::move(active)); } -#line 5534 "reflect.h2" +#line 5545 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle type_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5539 "reflect.h2" +#line 5550 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 5544 "reflect.h2" +#line 5555 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Remove this hack when statements like compound_statement can access their root statement. last_params = CPP2_UFCS(get_parameters)(stmt); base::traverse(stmt); } -#line 5551 "reflect.h2" +#line 5562 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ autodiff_stmt_handler ad {ctx, mf}; autodiff_stmt_handler ad_push_pop {ctx, mf}; @@ -9587,7 +9598,7 @@ auto i{0}; CPP2_UFCS(add_reverse_backprop)(diff, "{\n"); } -#line 5586 "reflect.h2" +#line 5597 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ if (CPP2_UFCS(has_expression)(stmt)) { // Return with expression. @@ -9604,7 +9615,7 @@ auto i{0}; } } -#line 5602 "reflect.h2" +#line 5613 "reflect.h2" [[nodiscard]] auto autodiff_stmt_handler::reverse_next(cpp2::impl::in expr) const& -> std::string{ if (CPP2_UFCS(contains)(expr, "+=")) { return string_util::replace_all(expr, "+=", "-="); @@ -9619,7 +9630,7 @@ auto i{0}; } -#line 5617 "reflect.h2" +#line 5628 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ auto diff_params {handle_stmt_parameters(last_params)}; @@ -9717,7 +9728,7 @@ auto i{0}; }} } -#line 5715 "reflect.h2" +#line 5726 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in stmt) -> void{ // TODO: Currently assuming that nothing bad happens in the condition diff += "if " + cpp2::to_string(CPP2_UFCS(to_string)(CPP2_UFCS(get_expression)(stmt))) + ""; @@ -9729,12 +9740,12 @@ auto i{0}; } } -#line 5726 "reflect.h2" +#line 5737 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in expr) -> void{ base::traverse(expr); } -#line 5730 "reflect.h2" +#line 5741 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ autodiff_activity_check ada {ctx}; CPP2_UFCS(pre_traverse)(ada, CPP2_UFCS(get_lhs_postfix_expression)(binexpr)); @@ -9786,73 +9797,73 @@ auto i{0}; } } -#line 5781 "reflect.h2" +#line 5792 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical or expressions are not yet handled as standalone statements."); } -#line 5785 "reflect.h2" +#line 5796 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Logical and expressions are not yet handled as standalone statements."); } -#line 5789 "reflect.h2" +#line 5800 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit or expressions are not yet handled as standalone statements."); } -#line 5793 "reflect.h2" +#line 5804 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit xor expressions are not yet handled as standalone statements."); } -#line 5797 "reflect.h2" +#line 5808 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Bit and expressions are not yet handled as standalone statements."); } -#line 5801 "reflect.h2" +#line 5812 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Equality or expressions are not yet handled as standalone statements."); } -#line 5805 "reflect.h2" +#line 5816 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Relational expressions are not yet handled as standalone statements."); } -#line 5809 "reflect.h2" +#line 5820 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Compare or expressions are not yet handled as standalone statements."); } -#line 5813 "reflect.h2" +#line 5824 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Shift or expressions are not yet handled as standalone statements."); } -#line 5817 "reflect.h2" +#line 5828 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Additive expressions are not yet handled as standalone statements."); } -#line 5821 "reflect.h2" +#line 5832 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in binexpr) -> void{ CPP2_UFCS(error)(binexpr, "AD: Multiplicative expressions are not yet handled as standalone statements."); } -#line 5825 "reflect.h2" +#line 5836 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in isas) -> void{ CPP2_UFCS(error)(isas, "AD: Is as expressions are not yet handled as standalone statements."); } -#line 5829 "reflect.h2" +#line 5840 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in prefix) -> void { CPP2_UFCS(error)(prefix, "AD: Prefix expressions are not yet handled as standalone statements."); } -#line 5834 "reflect.h2" +#line 5845 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in postfix) -> void { auto terms {CPP2_UFCS(get_terms)(postfix)}; @@ -9861,7 +9872,7 @@ auto i{0}; { auto i{0}; -#line 5841 "reflect.h2" +#line 5852 "reflect.h2" for ( auto const& term : terms ) { do { if (CPP2_UFCS(get_op)(term) == ".") { continue; @@ -9876,7 +9887,7 @@ auto i{0}; } // Check for function call, everything else is not handled. -#line 5854 "reflect.h2" +#line 5865 "reflect.h2" if (!((cpp2::move(is_func)))) { CPP2_UFCS(error)(postfix, "AD: Postfix expressions are only handled for function calls, or member function calls. Do not know how to handle: " + cpp2::to_string(CPP2_UFCS(to_string)(postfix)) + ""); return ; @@ -9889,27 +9900,27 @@ auto i{0}; append(cpp2::move(ad)); } -#line 5866 "reflect.h2" +#line 5877 "reflect.h2" auto autodiff_stmt_handler::traverse(cpp2::impl::in primary) -> void { CPP2_UFCS(error)(primary, "AD: Primary expressions are not yet handled as standalone statements."); } -#line 5883 "reflect.h2" +#line 5894 "reflect.h2" autodiff_declaration_handler::autodiff_declaration_handler(cpp2::impl::in ctx_, cpp2::impl::in decl_) : simple_traverser{ } , autodiff_handler_base{ ctx_ } , decl{ decl_ }{ -#line 5886 "reflect.h2" +#line 5897 "reflect.h2" } -#line 5888 "reflect.h2" +#line 5899 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in decl_) -> void{ base::traverse(decl_); } -#line 5893 "reflect.h2" +#line 5904 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in f) -> void{ CPP2_UFCS(enter_function)((*cpp2::impl::assert_not_null(ctx))); @@ -10039,10 +10050,10 @@ auto i{0}; return ; } -#line 6023 "reflect.h2" +#line 6034 "reflect.h2" autodiff_stmt_handler ad_impl {&*cpp2::impl::assert_not_null(ctx), f}; -#line 6026 "reflect.h2" +#line 6037 "reflect.h2" for ( auto const& stmt : CPP2_UFCS(get_statements)(CPP2_UFCS(get_compound_body)(f)) ) { ad_impl.pre_traverse(stmt); @@ -10067,7 +10078,7 @@ auto i{0}; CPP2_UFCS(add_as_differentiated)((*cpp2::impl::assert_not_null(ctx)), f); } -#line 6051 "reflect.h2" +#line 6062 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in o) -> void{ std::string ad_name {"" + cpp2::to_string(CPP2_UFCS(name)(o)) + cpp2::to_string((*cpp2::impl::assert_not_null(ctx)).fwd_suffix) + ""}; std::string fwd_ad_type {CPP2_UFCS(get_fwd_ad_type)((*cpp2::impl::assert_not_null(ctx)), CPP2_UFCS(type)(o))}; @@ -10095,7 +10106,7 @@ auto i{0}; CPP2_UFCS(add_variable_declaration)((*cpp2::impl::assert_not_null(ctx)), "" + cpp2::to_string(CPP2_UFCS(name)(o)) + "", "" + cpp2::to_string(CPP2_UFCS(type)(o)) + "", true, true);// TODO_a: Add acitivty check } -#line 6079 "reflect.h2" +#line 6090 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(push_stack)((*cpp2::impl::assert_not_null(ctx)), t); autodiff_declaration_handler ad {ctx, t}; @@ -10119,17 +10130,17 @@ auto i{0}; } } -#line 6103 "reflect.h2" +#line 6114 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in t) -> void{ CPP2_UFCS(error)(t, "AD: Do not know how to handle parameter_declaration: " + cpp2::to_string(CPP2_UFCS(to_string)(t)) + ""); } -#line 6108 "reflect.h2" +#line 6119 "reflect.h2" auto autodiff_declaration_handler::traverse(cpp2::impl::in stmt) -> void{ CPP2_UFCS(error)(stmt, "AD: Do not know how to handle statement in declaration context: " + cpp2::to_string(CPP2_UFCS(to_string)(stmt)) + ""); } -#line 6114 "reflect.h2" +#line 6125 "reflect.h2" auto autodiff(meta::type_declaration& t) -> void { @@ -10308,7 +10319,7 @@ return expression_flags::none; [[nodiscard]] auto expression_flags::from_code(cpp2::impl::in s) -> expression_flags{ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::move(str), "expression_flags::", "")); } -#line 6202 "reflect.h2" +#line 6213 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -10324,11 +10335,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 6218 "reflect.h2" +#line 6229 "reflect.h2" // Possible modifiers for a regular expression. // -#line 6222 "reflect.h2" +#line 6233 "reflect.h2" // mod: i // mod: m // mod: s @@ -10336,116 +10347,116 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 6231 "reflect.h2" +#line 6242 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 6240 "reflect.h2" +#line 6251 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 6242 "reflect.h2" +#line 6253 "reflect.h2" } -#line 6244 "reflect.h2" +#line 6255 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 6246 "reflect.h2" +#line 6257 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. // Create a reverse token for look behind expressions. -#line 6252 "reflect.h2" +#line 6263 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 6253 "reflect.h2" +#line 6264 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 6254 "reflect.h2" +#line 6265 "reflect.h2" auto regex_token::set_string(cpp2::impl::in s) & -> void{string_rep = s; } regex_token::~regex_token() noexcept{}// Set the string representation. -#line 6269 "reflect.h2" +#line 6280 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 6272 "reflect.h2" +#line 6283 "reflect.h2" } -#line 6274 "reflect.h2" +#line 6285 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } -#line 6278 "reflect.h2" +#line 6289 "reflect.h2" [[nodiscard]] auto regex_token_check::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).check); } regex_token_check::~regex_token_check() noexcept{} -#line 6290 "reflect.h2" +#line 6301 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 6293 "reflect.h2" +#line 6304 "reflect.h2" } -#line 6295 "reflect.h2" +#line 6306 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } -#line 6299 "reflect.h2" +#line 6310 "reflect.h2" [[nodiscard]] auto regex_token_code::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this)), (*this).code); } regex_token_code::~regex_token_code() noexcept{} -#line 6309 "reflect.h2" +#line 6320 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 6311 "reflect.h2" +#line 6322 "reflect.h2" } -#line 6313 "reflect.h2" +#line 6324 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } -#line 6317 "reflect.h2" +#line 6328 "reflect.h2" [[nodiscard]] auto regex_token_empty::reverse() const -> token_ptr { return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, CPP2_UFCS(to_string)((*this))); } regex_token_empty::~regex_token_empty() noexcept{} -#line 6329 "reflect.h2" +#line 6340 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 6332 "reflect.h2" +#line 6343 "reflect.h2" } -#line 6334 "reflect.h2" +#line 6345 "reflect.h2" auto regex_token_list::generate_code(generation_context& ctx) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).generate_code(ctx); } } -#line 6340 "reflect.h2" +#line 6351 "reflect.h2" auto regex_token_list::add_groups(std::set& groups) const -> void{ for ( auto const& token : tokens ) { (*cpp2::impl::assert_not_null(token)).add_groups(groups); } } -#line 6346 "reflect.h2" +#line 6357 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -10454,7 +10465,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov return r; } -#line 6354 "reflect.h2" +#line 6365 "reflect.h2" [[nodiscard]] auto regex_token_list::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(tokens.size())}; @@ -10470,7 +10481,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 6382 "reflect.h2" +#line 6393 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -10478,14 +10489,14 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov static_cast(alternate_match_lists.insert(alternate_match_lists.end(), CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(new_list)))); } -#line 6390 "reflect.h2" +#line 6401 "reflect.h2" auto parse_context_group_state::swap(parse_context_group_state& t) & -> void{// NOLINT(performance-noexcept-swap) std::swap(cur_match_list, t.cur_match_list); std::swap(alternate_match_lists, t.alternate_match_lists); std::swap(modifiers, t.modifiers); } -#line 6397 "reflect.h2" +#line 6408 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -10497,15 +10508,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 6409 "reflect.h2" +#line 6420 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 6414 "reflect.h2" +#line 6425 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 6418 "reflect.h2" +#line 6429 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -10526,7 +10537,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov , modifiers{ modifiers_ }{} parse_context_group_state::parse_context_group_state(){} -#line 6444 "reflect.h2" +#line 6455 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -10535,20 +10546,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 6453 "reflect.h2" +#line 6464 "reflect.h2" auto parse_context_branch_reset_state::set_next(cpp2::impl::in g) & -> void{ cur_group = g; max_group = max(max_group, g); } -#line 6459 "reflect.h2" +#line 6470 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 6466 "reflect.h2" +#line 6477 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -10563,16 +10574,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 6496 "reflect.h2" +#line 6507 "reflect.h2" parse_context::parse_context(cpp2::impl::in r, auto const& e) : regex{ r } , root{ CPP2_UFCS_TEMPLATE_NONLOCAL(cpp2_new)(cpp2::shared, "") } , error_out{ e }{ -#line 6500 "reflect.h2" +#line 6511 "reflect.h2" } -#line 6506 "reflect.h2" +#line 6517 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -10582,7 +10593,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6516 "reflect.h2" +#line 6527 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -10590,17 +10601,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 6523 "reflect.h2" +#line 6534 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 6527 "reflect.h2" +#line 6538 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 6534 "reflect.h2" +#line 6545 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -10610,7 +10621,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 6543 "reflect.h2" +#line 6554 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -10618,24 +10629,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 6550 "reflect.h2" +#line 6561 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 6558 "reflect.h2" +#line 6569 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 6562 "reflect.h2" +#line 6573 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 6566 "reflect.h2" +#line 6577 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -10647,22 +10658,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6577 "reflect.h2" +#line 6588 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 6583 "reflect.h2" +#line 6594 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 6587 "reflect.h2" +#line 6598 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 6591 "reflect.h2" +#line 6602 "reflect.h2" auto parse_context::set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void { if (!(named_groups.contains(name))) {// Redefinition of group name is not an error. The left most one is retained. @@ -10670,7 +10681,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6598 "reflect.h2" +#line 6609 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -10682,10 +10693,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6611 "reflect.h2" +#line 6622 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 6614 "reflect.h2" +#line 6625 "reflect.h2" [[nodiscard]] auto parse_context::get_next_position(cpp2::impl::in in_class, cpp2::impl::in no_skip) const& -> size_t { auto perl_syntax {false}; @@ -10725,7 +10736,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 6654 "reflect.h2" +#line 6665 "reflect.h2" [[nodiscard]] auto parse_context::next_impl(cpp2::impl::in in_class, cpp2::impl::in no_skip) & -> bool { pos = get_next_position(in_class, no_skip); @@ -10737,14 +10748,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6665 "reflect.h2" +#line 6676 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> decltype(auto) { return next_impl(false, false); } -#line 6666 "reflect.h2" +#line 6677 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> decltype(auto) { return next_impl(true, false); } -#line 6667 "reflect.h2" +#line 6678 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> decltype(auto) { return next_impl(false, true); } -#line 6669 "reflect.h2" +#line 6680 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -10754,10 +10765,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6678 "reflect.h2" +#line 6689 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 6680 "reflect.h2" +#line 6691 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_impl(cpp2::impl::in e, cpp2::impl::out r, cpp2::impl::in any) & -> bool { auto end {pos}; // NOLINT(clang-analyzer-deadcode.DeadStores) @@ -10779,14 +10790,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6701 "reflect.h2" +#line 6712 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 6702 "reflect.h2" +#line 6713 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 6703 "reflect.h2" +#line 6714 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> decltype(auto) { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 6705 "reflect.h2" +#line 6716 "reflect.h2" [[nodiscard]] auto parse_context::grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool { if (cpp2::impl::cmp_less_eq(pos + cpp2::impl::as_(n),regex.size())) { @@ -10800,7 +10811,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6718 "reflect.h2" +#line 6729 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -10822,7 +10833,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 6739 "reflect.h2" +#line 6750 "reflect.h2" [[nodiscard]] auto parse_context::peek_impl(cpp2::impl::in in_class) const& -> char{ auto next_pos {get_next_position(in_class, false)}; if (cpp2::impl::cmp_less(next_pos,regex.size())) { @@ -10833,12 +10844,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6749 "reflect.h2" +#line 6760 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> decltype(auto) { return peek_impl(false); } -#line 6750 "reflect.h2" +#line 6761 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> decltype(auto) { return peek_impl(true); } -#line 6755 "reflect.h2" +#line 6766 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -10893,7 +10904,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6809 "reflect.h2" +#line 6820 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -10933,7 +10944,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 6848 "reflect.h2" +#line 6859 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -10949,21 +10960,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 6865 "reflect.h2" +#line 6876 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> decltype(auto) { return pos; } -#line 6866 "reflect.h2" +#line 6877 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> decltype(auto) { return std::string(regex.substr(start, end - start + 1)); } -#line 6867 "reflect.h2" +#line 6878 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 6869 "reflect.h2" +#line 6880 "reflect.h2" [[nodiscard]] auto parse_context::error(cpp2::impl::in err) & -> token_ptr{ has_error = true; error_out("Error during parsing of regex '" + cpp2::to_string(regex) + "' at position '" + cpp2::to_string(pos) + "': " + cpp2::to_string(err) + ""); return nullptr; } -#line 6884 "reflect.h2" +#line 6895 "reflect.h2" auto generation_function_context::add_tabs(cpp2::impl::in c) & -> void{ int i {0}; for( ; cpp2::impl::cmp_less(i,c); i += 1 ) { @@ -10971,7 +10982,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 6891 "reflect.h2" +#line 6902 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -10981,22 +10992,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 6909 "reflect.h2" +#line 6920 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 6914 "reflect.h2" +#line 6925 "reflect.h2" auto generation_context::add(cpp2::impl::in s) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + cpp2::to_string(s) + "\n"; } -#line 6920 "reflect.h2" +#line 6931 "reflect.h2" auto generation_context::add_check(cpp2::impl::in check) & -> void{ auto cur {get_current()}; (*cpp2::impl::assert_not_null(cur)).code += "" + cpp2::to_string((*cpp2::impl::assert_not_null(cur)).tabs) + "if !cpp2::regex::" + cpp2::to_string(check) + " { r.matched = false; break; }\n"; } -#line 6926 "reflect.h2" +#line 6937 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -11005,7 +11016,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 6934 "reflect.h2" +#line 6945 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -11017,7 +11028,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 6945 "reflect.h2" +#line 6956 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -11025,7 +11036,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 6952 "reflect.h2" +#line 6963 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -11046,7 +11057,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 6973 "reflect.h2" +#line 6984 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -11056,7 +11067,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 6983 "reflect.h2" +#line 6994 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -11079,33 +11090,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 7007 "reflect.h2" +#line 7018 "reflect.h2" [[nodiscard]] auto generation_context::gen_func_name() & -> std::string{ auto cur_id {matcher_func}; matcher_func += 1; return "func_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 7013 "reflect.h2" +#line 7024 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 7017 "reflect.h2" +#line 7028 "reflect.h2" [[nodiscard]] auto generation_context::gen_reset_func_name() & -> std::string{ auto cur_id {reset_func}; reset_func += 1; return "reset_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 7023 "reflect.h2" +#line 7034 "reflect.h2" [[nodiscard]] auto generation_context::gen_temp() & -> std::string{ auto cur_id {temp_name}; temp_name += 1; return "tmp_" + cpp2::to_string(cpp2::move(cur_id)) + ""; } -#line 7031 "reflect.h2" +#line 7042 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -11114,7 +11125,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 7039 "reflect.h2" +#line 7050 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -11123,22 +11134,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 7049 "reflect.h2" +#line 7060 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 7053 "reflect.h2" +#line 7064 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 7057 "reflect.h2" +#line 7068 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 7061 "reflect.h2" +#line 7072 "reflect.h2" [[nodiscard]] auto generation_context::create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string { std::string res {"get_named_group_index: (name) -> int = {\n"}; @@ -11162,18 +11173,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 7086 "reflect.h2" +#line 7097 "reflect.h2" [[nodiscard]] auto generation_context::run(cpp2::impl::in token) & -> std::string{ entry_func = generate_func(token); return (*cpp2::impl::assert_not_null(get_base())).code; } -#line 7101 "reflect.h2" +#line 7112 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 7103 "reflect.h2" +#line 7114 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -11184,15 +11195,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 7118 "reflect.h2" +#line 7129 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 7121 "reflect.h2" +#line 7132 "reflect.h2" } -#line 7123 "reflect.h2" +#line 7134 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -11210,7 +11221,7 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::alternative_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", other, " + cpp2::to_string(next_name) + " " + cpp2::to_string(cpp2::move(functions)) + ")"); } -#line 7140 "reflect.h2" +#line 7151 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -11218,7 +11229,7 @@ generation_function_context::generation_function_context(){} } } -#line 7147 "reflect.h2" +#line 7158 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -11232,7 +11243,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7160 "reflect.h2" +#line 7171 "reflect.h2" [[nodiscard]] auto alternative_token_gen::reverse() const -> token_ptr{ int s {cpp2::unchecked_narrow(alternatives.size())}; @@ -11248,14 +11259,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 7181 "reflect.h2" +#line 7192 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 7183 "reflect.h2" +#line 7194 "reflect.h2" } -#line 7185 "reflect.h2" +#line 7196 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -11264,11 +11275,11 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 7200 "reflect.h2" +#line 7211 "reflect.h2" atomic_group_token::atomic_group_token() : regex_token{ "" }{} -#line 7202 "reflect.h2" +#line 7213 "reflect.h2" [[nodiscard]] auto atomic_group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).inner_token = CPP2_UFCS(reverse)((*cpp2::impl::assert_not_null(inner_token))); @@ -11276,7 +11287,7 @@ generation_function_context::generation_function_context(){} return r; } -#line 7209 "reflect.h2" +#line 7220 "reflect.h2" auto atomic_group_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -11285,37 +11296,37 @@ generation_function_context::generation_function_context(){} ctx.add_statefull(next_name, "cpp2::regex::atomic_group_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 7217 "reflect.h2" +#line 7228 "reflect.h2" auto atomic_group_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } atomic_group_token::~atomic_group_token() noexcept{} -#line 7231 "reflect.h2" +#line 7242 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ std::string(1, t) } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7235 "reflect.h2" +#line 7246 "reflect.h2" } -#line 7237 "reflect.h2" +#line 7248 "reflect.h2" char_token::char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_) : regex_token{ t } , token{ t } , ignore_case{ ignore_case_ }{ -#line 7241 "reflect.h2" +#line 7252 "reflect.h2" } -#line 7243 "reflect.h2" +#line 7254 "reflect.h2" [[nodiscard]] auto char_token::parse(parse_context& ctx) -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, ctx.current(), ctx.get_modifiers().has(expression_flags::case_insensitive)); } -#line 7247 "reflect.h2" +#line 7258 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -11324,14 +11335,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 7253 "reflect.h2" +#line 7264 "reflect.h2" for( ; cpp2::impl::cmp_less(i,token.size()); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(lower, i) = string_util::safe_tolower(CPP2_ASSERT_IN_BOUNDS(token, i)); CPP2_ASSERT_IN_BOUNDS(upper, i) = string_util::safe_toupper(CPP2_ASSERT_IN_BOUNDS(token, i)); } } -#line 7258 "reflect.h2" +#line 7269 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -11344,7 +11355,7 @@ size_t i{0}; } } -#line 7270 "reflect.h2" +#line 7281 "reflect.h2" auto char_token::gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11366,7 +11377,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7291 "reflect.h2" +#line 7302 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -11385,7 +11396,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 7309 "reflect.h2" +#line 7320 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -11401,14 +11412,14 @@ size_t i{0}; return cpp2::move(str); } -#line 7324 "reflect.h2" +#line 7335 "reflect.h2" [[nodiscard]] auto char_token::reverse() const -> token_ptr{ std::string reverse_str {token}; std::reverse(reverse_str.begin(), reverse_str.end()); return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(reverse_str), ignore_case); } -#line 7330 "reflect.h2" +#line 7341 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -11416,19 +11427,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 7347 "reflect.h2" +#line 7358 "reflect.h2" class_token::class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str) : regex_token{ str } , negate{ negate_ } , case_insensitive{ case_insensitive_ } , class_str{ class_str_ } -#line 7348 "reflect.h2" +#line 7359 "reflect.h2" { -#line 7353 "reflect.h2" +#line 7364 "reflect.h2" } -#line 7356 "reflect.h2" +#line 7367 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -11554,7 +11565,7 @@ size_t i{0}; ); } -#line 7481 "reflect.h2" +#line 7492 "reflect.h2" [[nodiscard]] auto class_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, negate, @@ -11564,13 +11575,13 @@ size_t i{0}; ); } -#line 7490 "reflect.h2" +#line 7501 "reflect.h2" auto class_token::generate_code(generation_context& ctx) const -> void { ctx.add_check("class_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ")"); } -#line 7495 "reflect.h2" +#line 7506 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -11581,12 +11592,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 7507 "reflect.h2" +#line 7518 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 7512 "reflect.h2" +#line 7523 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -11620,7 +11631,7 @@ size_t i{0}; } -#line 7548 "reflect.h2" +#line 7559 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -11629,19 +11640,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 7571 "reflect.h2" +#line 7582 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in reverse_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } , reverse_eval{ reverse_ } -#line 7572 "reflect.h2" +#line 7583 "reflect.h2" { -#line 7577 "reflect.h2" +#line 7588 "reflect.h2" } -#line 7579 "reflect.h2" +#line 7590 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -11743,19 +11754,19 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), false, cpp2::move(str)); } -#line 7680 "reflect.h2" +#line 7691 "reflect.h2" [[nodiscard]] auto group_ref_token::reverse() const -> token_ptr{ return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, id, case_insensitive, !(reverse_eval), to_string()); } -#line 7684 "reflect.h2" +#line 7695 "reflect.h2" auto group_ref_token::generate_code(generation_context& ctx) const -> void{ ctx.add_check("group_ref_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ")"); } group_ref_token::~group_ref_token() noexcept{} -#line 7708 "reflect.h2" +#line 7719 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead_lookbehind(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in lookahead, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11774,7 +11785,7 @@ size_t i{0}; return r; } -#line 7726 "reflect.h2" +#line 7737 "reflect.h2" [[nodiscard]] auto group_token::parse_atomic_pattern(parse_context& ctx, cpp2::impl::in syntax) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -11789,7 +11800,7 @@ size_t i{0}; return r; } -#line 7740 "reflect.h2" +#line 7751 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -11949,7 +11960,7 @@ size_t i{0}; } } -#line 7899 "reflect.h2" +#line 7910 "reflect.h2" [[nodiscard]] auto group_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).number = number; @@ -11958,7 +11969,7 @@ size_t i{0}; return r; } -#line 7907 "reflect.h2" +#line 7918 "reflect.h2" [[nodiscard]] auto group_token::gen_string(cpp2::impl::in name, cpp2::impl::in name_brackets, cpp2::impl::in has_modifier, cpp2::impl::in modifiers, cpp2::impl::in inner_) -> std::string { std::string start {"("}; @@ -11977,7 +11988,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 7925 "reflect.h2" +#line 7936 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -12009,7 +12020,7 @@ size_t i{0}; } } -#line 7956 "reflect.h2" +#line 7967 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -12020,7 +12031,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 7968 "reflect.h2" +#line 7979 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -12059,7 +12070,7 @@ size_t i{0}; return r; } -#line 8009 "reflect.h2" +#line 8020 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -12077,7 +12088,7 @@ size_t i{0}; }} } -#line 8029 "reflect.h2" +#line 8040 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -12091,16 +12102,16 @@ size_t i{0}; } } -#line 8055 "reflect.h2" +#line 8066 "reflect.h2" lookahead_lookbehind_token::lookahead_lookbehind_token(cpp2::impl::in lookahead_, cpp2::impl::in positive_) : regex_token{ "" } , lookahead{ lookahead_ } , positive{ positive_ }{ -#line 8058 "reflect.h2" +#line 8069 "reflect.h2" } -#line 8060 "reflect.h2" +#line 8071 "reflect.h2" auto lookahead_lookbehind_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; @@ -12112,7 +12123,7 @@ size_t i{0}; } } -#line 8071 "reflect.h2" +#line 8082 "reflect.h2" [[nodiscard]] auto lookahead_lookbehind_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, lookahead, positive)}; (*cpp2::impl::assert_not_null(r)).inner = inner;// We do not reverse here. Nested lookahead and lookbehind stay as they are. @@ -12120,14 +12131,14 @@ size_t i{0}; return r; } -#line 8078 "reflect.h2" +#line 8089 "reflect.h2" auto lookahead_lookbehind_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_lookbehind_token::~lookahead_lookbehind_token() noexcept{} -#line 8086 "reflect.h2" +#line 8097 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12153,7 +12164,7 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\" + cpp2::to_string(ctx.current()) + "", "" + cpp2::to_string(cpp2::move(name)) + "::match"); } -#line 8114 "reflect.h2" +#line 8125 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -12179,11 +12190,11 @@ size_t i{0}; return r; } -#line 8151 "reflect.h2" +#line 8162 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 8153 "reflect.h2" +#line 8164 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12257,7 +12268,7 @@ size_t i{0}; return nullptr; } -#line 8226 "reflect.h2" +#line 8237 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -12270,7 +12281,7 @@ size_t i{0}; }} } -#line 8238 "reflect.h2" +#line 8249 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -12284,7 +12295,7 @@ size_t i{0}; }} } -#line 8251 "reflect.h2" +#line 8262 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -12304,7 +12315,7 @@ size_t i{0}; return r; } -#line 8270 "reflect.h2" +#line 8281 "reflect.h2" [[nodiscard]] auto range_token::reverse() const -> token_ptr{ auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; (*cpp2::impl::assert_not_null(r)).min_count = min_count; @@ -12315,7 +12326,7 @@ size_t i{0}; return r; } -#line 8280 "reflect.h2" +#line 8291 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -12327,14 +12338,14 @@ size_t i{0}; ctx.add_statefull(next_name, "cpp2::regex::range_token_matcher::match(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ", " + cpp2::to_string(cpp2::move(reset_name)) + ", other, " + cpp2::to_string(next_name) + ")"); } -#line 8291 "reflect.h2" +#line 8302 "reflect.h2" auto range_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner_token)).add_groups(groups); } range_token::~range_token() noexcept{} -#line 8303 "reflect.h2" +#line 8314 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -12358,7 +12369,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 8327 "reflect.h2" +#line 8338 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -12368,7 +12379,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 8339 "reflect.h2" +#line 8350 "reflect.h2" [[nodiscard]] auto start_match_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12384,7 +12395,7 @@ size_t i{0}; } } -#line 8359 "reflect.h2" +#line 8370 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -12402,15 +12413,15 @@ size_t i{0}; }} } -#line 8395 "reflect.h2" +#line 8406 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 8398 "reflect.h2" +#line 8409 "reflect.h2" } -#line 8400 "reflect.h2" +#line 8411 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -12446,7 +12457,7 @@ size_t i{0}; return source; } -#line 8435 "reflect.h2" +#line 8446 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -12462,7 +12473,7 @@ size_t i{0}; } } -#line 8451 "reflect.h2" +#line 8462 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -12471,7 +12482,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -12526,7 +12537,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 8520 "reflect.h2" +#line 8531 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -12654,7 +12665,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 8648 "reflect.h2" +#line 8659 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index d7e5196e1..f7811b410 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -5187,7 +5187,8 @@ autodiff_expression_handler: type = { traverse: (override inout this, binexpr: meta::additive_expression) = { terms := binexpr.get_terms(); - first := true; + first := true; + first_fwd := true; op : std::string = "+"; fwd : std::string = ""; rws : std::string = ""; @@ -5195,15 +5196,25 @@ autodiff_expression_handler: type = { for terms do (term) { if !first { op = term.get_op().to_string(); - fwd += " (op)$ "; primal += " (op)$ "; - } var := handle_expression_term(term.get_term()); if var.active { - fwd += var.fwd; + if first_fwd { + if op == "-" {// Special handling for first fwd termn with minus + fwd += "-(var.fwd)$"; + } + else { // Special handling for first fwd term with plus + fwd += var.fwd; + } + } + else { + fwd += "(op)$ (var.fwd)$"; + } rws += "(var.rws)$ (op)$= _rb_;\n"; + + first_fwd = false; } primal += var.primal; From 4cd35d0f2a4071229aabbee1f8e0aa2bd66cc036 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Mon, 8 Sep 2025 16:06:18 -0700 Subject: [PATCH 54/54] Add an AD unit test --- regression-tests/pure2-autodiff.cpp2 | 17 +++++ .../pure2-autodiff.cpp.output | 14 ++++ .../test-results/pure2-autodiff.cpp | 74 ++++++++++++++++++- .../test-results/pure2-autodiff.cpp2.output | 59 +++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) diff --git a/regression-tests/pure2-autodiff.cpp2 b/regression-tests/pure2-autodiff.cpp2 index 9394acfcf..7438068d5 100644 --- a/regression-tests/pure2-autodiff.cpp2 +++ b/regression-tests/pure2-autodiff.cpp2 @@ -277,6 +277,23 @@ write_output_reverse: (func: std::string, x: double, inout x_b: double, y: doubl y_b = 0.0; } +ad_test_2: @autodiff<"order=2"> @print type = { + f: (x: double) -> (y: double) = { + if x < -3 + { + y = x * x; + } + else if x < 3 + { + y = x + sin(x) + 10; + } + else + { + y = sin(x) * x*x; + } + } +} + main: () = { x: double = 2.0; diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output index 32eadc310..18a6df6f0 100644 --- a/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-autodiff.cpp.output @@ -1 +1,15 @@ pure2-autodiff.cpp +C:\github\cppfront\include\cpp2util.h(1250): error C7595: 'std::source_location::current': call to immediate function is not a constant expression +C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\source_location(37): note: failure was caused by attempting to access a member on an object of dynamic type 'std::source_location' in which the member is not defined +C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\source_location(37): note: see usage of 'std::source_location::source_location' +C:\github\cppfront\include\cpp2util.h(1250): note: the call stack of the evaluation (the oldest call first) is +C:\github\cppfront\include\cpp2util.h(1250): note: while evaluating function 'std::source_location std::source_location::current(const uint_least32_t,const uint_least32_t,const char *const ,const char *const ) noexcept' +C:\github\cppfront\include\cpp2util.h(1250): note: the template instantiation context (the oldest one first) is +pure2-autodiff.cpp2(282): note: see reference to class template instantiation 'cpp2::taylor' being compiled +cpp2taylor.h2(16): note: while compiling class template member function 'cpp2::taylor::taylor(const std::initializer_list &)' + with + [ + R=double + ] +pure2-autodiff.cpp2(298): note: see the first reference to 'cpp2::taylor::taylor' in 'ad_test_2::f_d' +cpp2taylor.h2(35): note: while compiling class template member function 'void cpp2::taylor::set(const int,const double) &' diff --git a/regression-tests/test-results/pure2-autodiff.cpp b/regression-tests/test-results/pure2-autodiff.cpp index 20bd9f962..f4c551bd4 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp +++ b/regression-tests/test-results/pure2-autodiff.cpp @@ -1,6 +1,7 @@ #define CPP2_IMPORT_STD Yes #include "cpp2ad_stack.h" +#include "cpp2taylor.h" //=== Cpp2 type declarations ==================================================== @@ -28,6 +29,10 @@ class ad_test_reverse; class ad_test_twice; +#line 280 "pure2-autodiff.cpp2" +class ad_test_2; + + //=== Cpp2 type definitions and function declarations =========================== #line 1 "pure2-autodiff.cpp2" @@ -532,6 +537,24 @@ auto write_output(cpp2::impl::in func, cpp2::impl::in x, cp auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x, double& x_b, cpp2::impl::in y, double& y_b, double& r_b, auto const& ret) -> void; #line 280 "pure2-autodiff.cpp2" +class ad_test_2 { +using f_ret = double; + +#line 281 "pure2-autodiff.cpp2" + public: [[nodiscard]] static auto f(cpp2::impl::in x) -> f_ret; +struct f_d_ret { double y; cpp2::taylor y_d; }; + + + public: [[nodiscard]] static auto f_d(cpp2::impl::in x, cpp2::impl::in> x_d) -> f_d_ret; + + public: ad_test_2() = default; + public: ad_test_2(ad_test_2 const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(ad_test_2 const&) -> void = delete; + + +#line 295 "pure2-autodiff.cpp2" +}; + auto main() -> int; //=== Cpp2 function definitions ================================================= @@ -1552,7 +1575,56 @@ auto write_output_reverse(cpp2::impl::in func, cpp2::impl::in x) -> f_ret{ + cpp2::impl::deferred_init y; +#line 282 "pure2-autodiff.cpp2" + if (cpp2::impl::cmp_less(x,-3)) + { + y.construct(x * x); + } + else {if (cpp2::impl::cmp_less(x,3)) + { + y.construct(x + sin(x) + 10); + } + else + { + y.construct(sin(x) * x * x); + }}return std::move(y.value()); + } + + [[nodiscard]] auto ad_test_2::f_d(cpp2::impl::in x, cpp2::impl::in> x_d) -> f_d_ret{ + double y {0.0}; + cpp2::taylor y_d {0.0};if (cpp2::impl::cmp_less(x,-3)) { + y_d = x_d.mul(x_d, x, x); + y = x * x; + } + else { + if (cpp2::impl::cmp_less(x,3)) { + + cpp2::taylor temp_1_d {CPP2_UFCS(sin)(x_d, x)}; + + double temp_1 {sin(x)}; + y_d = x_d + cpp2::move(temp_1_d); + y = x + cpp2::move(temp_1) + 10; + } + else { + + cpp2::taylor temp_3_d {CPP2_UFCS(sin)(x_d, x)}; + + double temp_3 {sin(x)}; + + auto temp_4_d {cpp2::move(temp_3_d).mul(x_d, temp_3, x)}; + + auto temp_4 {cpp2::move(temp_3) * x}; + y_d = cpp2::move(temp_4_d).mul(x_d, temp_4, x); + y = cpp2::move(temp_4) * x; + } + } + return { std::move(y), std::move(y_d) }; + } + +#line 297 "pure2-autodiff.cpp2" auto main() -> int{ double x {2.0}; diff --git a/regression-tests/test-results/pure2-autodiff.cpp2.output b/regression-tests/test-results/pure2-autodiff.cpp2.output index 767174482..9ac7a9233 100644 --- a/regression-tests/test-results/pure2-autodiff.cpp2.output +++ b/regression-tests/test-results/pure2-autodiff.cpp2.output @@ -1386,5 +1386,64 @@ ad_test_twice:/* @autodiff @autodiff<"suffix=_d2"> @print */ type = return; } } + + +ad_test_2:/* @autodiff<"order=2"> @print */ type = +{ + f:(in x: double, ) -> (out y: double, ) = + { + if x < -3 + { + y = x * x; + } + else + { + if x < 3 + { + y = x + sin(x) + 10; + } + else + { + y = sin(x) * x * x; + } + } + return; + } + + f_d:( + in x: double, + in x_d: cpp2::taylor, + ) -> ( + out y: double = 0.0, + out y_d: cpp2::taylor = 0.0, + ) = + { + if x < -3 + { + y_d = x_d..mul(x_d, x, x); + y = x * x; + } + else + { + if x < 3 + { + temp_1_d: cpp2::taylor = x_d.sin(x); + temp_1: double = sin(x); + y_d = x_d + temp_1_d; + y = x + temp_1 + 10; + } + else + { + temp_3_d: cpp2::taylor = x_d.sin(x); + temp_3: double = sin(x); + temp_4_d: _ = temp_3_d..mul(x_d, temp_3, x); + temp_4: _ = temp_3 * x; + y_d = temp_4_d..mul(x_d, temp_4, x); + y = temp_4 * x; + } + } + return; + } +} ok (all Cpp2, passes safety checks)