From baa69545e092ae3076877a94ce7f23297b6cb556 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Mon, 30 Sep 2024 15:25:31 -0700 Subject: [PATCH] Improve hash combination Per https://github.com/hsutter/cppfront/commit/4641ad2e3572efd9727fafa08f5fab6bb14d54b0#r147400088 --- .../pure2-hashable.cpp.execution | 2 +- .../gcc-10-c++20/pure2-hashable.cpp.output | 16 +- .../gcc-14-c++2b/pure2-hashable.cpp.execution | 2 +- .../pure2-hashable.cpp.execution | 2 +- .../test-results/pure2-hashable.cpp | 18 +- regression-tests/test-results/version | 2 +- source/build.info | 2 +- source/reflect.h | 806 +++++++++--------- source/reflect.h2 | 14 +- 9 files changed, 433 insertions(+), 431 deletions(-) diff --git a/regression-tests/test-results/clang-12-c++20/pure2-hashable.cpp.execution b/regression-tests/test-results/clang-12-c++20/pure2-hashable.cpp.execution index 8764cd3ff..0ec0d7a73 100644 --- a/regression-tests/test-results/clang-12-c++20/pure2-hashable.cpp.execution +++ b/regression-tests/test-results/clang-12-c++20/pure2-hashable.cpp.execution @@ -1 +1 @@ -10166087914140344613 \ No newline at end of file +6440649391998984779 \ No newline at end of file diff --git a/regression-tests/test-results/gcc-10-c++20/pure2-hashable.cpp.output b/regression-tests/test-results/gcc-10-c++20/pure2-hashable.cpp.output index 70b2ff0fa..3f9f10ffa 100644 --- a/regression-tests/test-results/gcc-10-c++20/pure2-hashable.cpp.output +++ b/regression-tests/test-results/gcc-10-c++20/pure2-hashable.cpp.output @@ -21,15 +21,15 @@ pure2-hashable.cpp2:1:7: note: candidates are: ‘constexpr base& base::operator pure2-hashable.cpp2:1:7: note: ‘constexpr base& base::operator=(const base&)’ pure2-hashable.cpp2:6:14: note: ‘template base& base::operator=(auto:97&&)’ pure2-hashable.cpp2:1:7: note: ‘class base’ defined here -pure2-hashable.cpp2:11:1: error: no declaration matches ‘mystruct::mystruct(auto:103&&, auto:104&&, auto:105&&) requires (is_convertible_v::type>::type, const std::add_const_t&>) && (is_convertible_v::type>::type, const std::__cxx11::add_const_t, std::allocator > >&>) && (is_convertible_v::type>::type, const std::add_const_t&>)’ +pure2-hashable.cpp2:17:1: error: no declaration matches ‘mystruct::mystruct(auto:103&&, auto:104&&, auto:105&&) requires (is_convertible_v::type>::type, const std::add_const_t&>) && (is_convertible_v::type>::type, const std::__cxx11::add_const_t, std::allocator > >&>) && (is_convertible_v::type>::type, const std::add_const_t&>)’ pure2-hashable.cpp2:5:7: note: candidates are: ‘mystruct::mystruct(mystruct&&)’ pure2-hashable.cpp2:5:7: note: ‘mystruct::mystruct(const mystruct&)’ pure2-hashable.cpp2:10:13: note: ‘template mystruct::mystruct(auto:98&&, auto:99&&, auto:100&&)’ pure2-hashable.cpp2:5:7: note: ‘class mystruct’ defined here -pure2-hashable.cpp2:14:104: error: mixing declarations and function-definitions is forbidden -pure2-hashable.cpp2:14:107: error: expected constructor, destructor, or type conversion before ‘{’ token -pure2-hashable.cpp2:15:104: error: expected unqualified-id before ‘,’ token -pure2-hashable.cpp2:15:107: error: expected constructor, destructor, or type conversion before ‘{’ token -pure2-hashable.cpp2:16:104: error: expected unqualified-id before ‘,’ token -pure2-hashable.cpp2:16:107: error: expected constructor, destructor, or type conversion before ‘{’ token -pure2-hashable.cpp2:16:127: error: expected unqualified-id before ‘{’ token +pure2-hashable.cpp2:20:104: error: mixing declarations and function-definitions is forbidden +pure2-hashable.cpp2:20:107: error: expected constructor, destructor, or type conversion before ‘{’ token +pure2-hashable.cpp2:21:104: error: expected unqualified-id before ‘,’ token +pure2-hashable.cpp2:21:107: error: expected constructor, destructor, or type conversion before ‘{’ token +pure2-hashable.cpp2:22:104: error: expected unqualified-id before ‘,’ token +pure2-hashable.cpp2:22:107: error: expected constructor, destructor, or type conversion before ‘{’ token +pure2-hashable.cpp2:22:127: error: expected unqualified-id before ‘{’ token diff --git a/regression-tests/test-results/gcc-14-c++2b/pure2-hashable.cpp.execution b/regression-tests/test-results/gcc-14-c++2b/pure2-hashable.cpp.execution index 8764cd3ff..0ec0d7a73 100644 --- a/regression-tests/test-results/gcc-14-c++2b/pure2-hashable.cpp.execution +++ b/regression-tests/test-results/gcc-14-c++2b/pure2-hashable.cpp.execution @@ -1 +1 @@ -10166087914140344613 \ No newline at end of file +6440649391998984779 \ No newline at end of file diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-hashable.cpp.execution b/regression-tests/test-results/msvc-2022-c++latest/pure2-hashable.cpp.execution index 1e1d01424..71a84de93 100644 --- a/regression-tests/test-results/msvc-2022-c++latest/pure2-hashable.cpp.execution +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-hashable.cpp.execution @@ -1 +1 @@ -13273923326899311054 \ No newline at end of file +13958440649017415620 \ No newline at end of file diff --git a/regression-tests/test-results/pure2-hashable.cpp b/regression-tests/test-results/pure2-hashable.cpp index 7b2c2c437..ae892642e 100644 --- a/regression-tests/test-results/pure2-hashable.cpp +++ b/regression-tests/test-results/pure2-hashable.cpp @@ -57,14 +57,28 @@ auto base::operator=(auto&& h_) -> base& requires (std::is_convertible_v&>) { h = CPP2_FORWARD(h_); return *this;} -[[nodiscard]] auto base::hash() const& -> size_t { return std::hash()(h); } +[[nodiscard]] auto base::hash() const& -> size_t{ + +size_t ret {0}; +ret ^= std::hash()(h) + (ret << 6) + (ret >> 2); +return ret; +} + mystruct::mystruct(auto&& i_, auto&& j_, auto&& k_) requires (std::is_convertible_v&> && std::is_convertible_v&> && std::is_convertible_v&>) : base{ (1) } , i{ CPP2_FORWARD(i_) } , j{ CPP2_FORWARD(j_) } , k{ CPP2_FORWARD(k_) }{} -[[nodiscard]] auto mystruct::hash() const& -> size_t { return base::hash() ^ (std::hash()(i) << 1) ^ (std::hash()(j) << 2) ^ (std::hash()(k) << 3); } +[[nodiscard]] auto mystruct::hash() const& -> size_t{ + +size_t ret {0}; +ret ^= base::hash() + (ret << 6) + (ret >> 2); +ret ^= std::hash()(i) + (ret << 6) + (ret >> 2); +ret ^= std::hash()(j) + (ret << 6) + (ret >> 2); +ret ^= std::hash()(k) + (ret << 6) + (ret >> 2); +return ret; +} #line 12 "pure2-hashable.cpp2" auto main() -> int{ mystruct x {2, "three", 4u}; diff --git a/regression-tests/test-results/version b/regression-tests/test-results/version index 0129313a6..1b2ac852d 100644 --- a/regression-tests/test-results/version +++ b/regression-tests/test-results/version @@ -1,5 +1,5 @@ -cppfront compiler v0.7.4 Build 9930:1028 +cppfront compiler v0.7.4 Build 9930:1349 Copyright(c) Herb Sutter All rights reserved SPDX-License-Identifier: CC-BY-NC-ND-4.0 diff --git a/source/build.info b/source/build.info index 1df4fffc8..28fcc4adc 100644 --- a/source/build.info +++ b/source/build.info @@ -1 +1 @@ -"9930:1028" \ No newline at end of file +"9930:1349" \ No newline at end of file diff --git a/source/reflect.h b/source/reflect.h index dcf3c7ff0..d2b2a073a 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -36,77 +36,77 @@ class type_declaration; #line 605 "reflect.h2" class alias_declaration; -#line 1061 "reflect.h2" +#line 1055 "reflect.h2" class value_member_info; -#line 1579 "reflect.h2" +#line 1573 "reflect.h2" class expression_flags; -#line 1595 "reflect.h2" +#line 1589 "reflect.h2" class regex_token; -#line 1621 "reflect.h2" +#line 1615 "reflect.h2" class regex_token_check; -#line 1640 "reflect.h2" +#line 1634 "reflect.h2" class regex_token_code; -#line 1659 "reflect.h2" +#line 1653 "reflect.h2" class regex_token_empty; -#line 1675 "reflect.h2" +#line 1669 "reflect.h2" class regex_token_list; -#line 1714 "reflect.h2" +#line 1708 "reflect.h2" class parse_context_group_state; -#line 1775 "reflect.h2" +#line 1769 "reflect.h2" class parse_context_branch_reset_state; -#line 1818 "reflect.h2" +#line 1812 "reflect.h2" class parse_context; -#line 2216 "reflect.h2" +#line 2210 "reflect.h2" class generation_function_context; -#line 2234 "reflect.h2" +#line 2228 "reflect.h2" class generation_context; -#line 2432 "reflect.h2" +#line 2426 "reflect.h2" class alternative_token; -#line 2447 "reflect.h2" +#line 2441 "reflect.h2" class alternative_token_gen; -#line 2499 "reflect.h2" +#line 2493 "reflect.h2" class any_token; -#line 2517 "reflect.h2" +#line 2511 "reflect.h2" class char_token; -#line 2620 "reflect.h2" +#line 2614 "reflect.h2" class class_token; -#line 2835 "reflect.h2" +#line 2829 "reflect.h2" class group_ref_token; -#line 2966 "reflect.h2" +#line 2960 "reflect.h2" class group_token; -#line 3253 "reflect.h2" +#line 3247 "reflect.h2" class lookahead_token; -#line 3334 "reflect.h2" +#line 3328 "reflect.h2" class range_token; -#line 3482 "reflect.h2" +#line 3476 "reflect.h2" class special_range_token; -#line 3549 "reflect.h2" +#line 3543 "reflect.h2" template class regex_generator; -#line 3793 "reflect.h2" +#line 3787 "reflect.h2" } } @@ -500,32 +500,32 @@ auto copyable(meta::type_declaration& t) -> void; #line 842 "reflect.h2" auto hashable(meta::type_declaration& t) -> void; -#line 881 "reflect.h2" +#line 875 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void; -#line 909 "reflect.h2" +#line 903 "reflect.h2" auto value(meta::type_declaration& t) -> void; -#line 915 "reflect.h2" +#line 909 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 921 "reflect.h2" +#line 915 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 950 "reflect.h2" +#line 944 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void; -#line 992 "reflect.h2" +#line 986 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void; -#line 1061 "reflect.h2" +#line 1055 "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 1065 "reflect.h2" +#line 1059 "reflect.h2" }; auto basic_enum( @@ -534,22 +534,22 @@ auto basic_enum( cpp2::impl::in bitwise ) -> void; -#line 1331 "reflect.h2" +#line 1325 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1358 "reflect.h2" +#line 1352 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void; -#line 1404 "reflect.h2" +#line 1398 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void; -#line 1555 "reflect.h2" +#line 1549 "reflect.h2" auto print(cpp2::impl::in t) -> void; -#line 1575 "reflect.h2" +#line 1569 "reflect.h2" using error_func = std::function x)>; -#line 1579 "reflect.h2" +#line 1573 "reflect.h2" class expression_flags { private: cpp2::u8 _value; private: constexpr expression_flags(cpp2::impl::in _val); @@ -584,20 +584,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 1587 "reflect.h2" +#line 1581 "reflect.h2" }; -#line 1595 "reflect.h2" +#line 1589 "reflect.h2" class regex_token { public: std::string string_rep; public: explicit regex_token(cpp2::impl::in str); -#line 1603 "reflect.h2" +#line 1597 "reflect.h2" public: explicit regex_token(); -#line 1608 "reflect.h2" +#line 1602 "reflect.h2" public: virtual auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void = 0; public: virtual auto add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void; @@ -608,24 +608,24 @@ class regex_token public: regex_token(regex_token const&) = delete; /* No 'that' constructor, suppress copy */ public: auto operator=(regex_token const&) -> void = delete; -#line 1613 "reflect.h2" +#line 1607 "reflect.h2" }; using token_ptr = std::shared_ptr; using token_vec = std::vector; -#line 1619 "reflect.h2" +#line 1613 "reflect.h2" // Adds a check in code generation. // class regex_token_check : public regex_token { -#line 1625 "reflect.h2" +#line 1619 "reflect.h2" private: std::string check; public: explicit regex_token_check(cpp2::impl::in str, cpp2::impl::in check_); -#line 1632 "reflect.h2" +#line 1626 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~regex_token_check() noexcept; @@ -633,21 +633,21 @@ class regex_token_check public: auto operator=(regex_token_check const&) -> void = delete; -#line 1635 "reflect.h2" +#line 1629 "reflect.h2" }; -#line 1638 "reflect.h2" +#line 1632 "reflect.h2" // Adds code in code generation. // class regex_token_code : public regex_token { -#line 1644 "reflect.h2" +#line 1638 "reflect.h2" private: std::string code; public: explicit regex_token_code(cpp2::impl::in str, cpp2::impl::in code_); -#line 1651 "reflect.h2" +#line 1645 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~regex_token_code() noexcept; @@ -655,19 +655,19 @@ class regex_token_code public: auto operator=(regex_token_code const&) -> void = delete; -#line 1654 "reflect.h2" +#line 1648 "reflect.h2" }; -#line 1657 "reflect.h2" +#line 1651 "reflect.h2" // Token that does not influence the matching. E.g. comment. // class regex_token_empty : public regex_token { -#line 1663 "reflect.h2" +#line 1657 "reflect.h2" public: explicit regex_token_empty(cpp2::impl::in str); -#line 1667 "reflect.h2" +#line 1661 "reflect.h2" public: auto generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void override; public: virtual ~regex_token_empty() noexcept; @@ -675,27 +675,27 @@ class regex_token_empty public: auto operator=(regex_token_empty const&) -> void = delete; -#line 1670 "reflect.h2" +#line 1664 "reflect.h2" }; -#line 1673 "reflect.h2" +#line 1667 "reflect.h2" // Represents a list of regex tokens as one token. // class regex_token_list : public regex_token { -#line 1679 "reflect.h2" +#line 1673 "reflect.h2" public: token_vec tokens; public: explicit regex_token_list(cpp2::impl::in t); -#line 1686 "reflect.h2" +#line 1680 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 1692 "reflect.h2" +#line 1686 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 1698 "reflect.h2" +#line 1692 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in vec) -> std::string; public: virtual ~regex_token_list() noexcept; @@ -703,10 +703,10 @@ class regex_token_list public: auto operator=(regex_token_list const&) -> void = delete; -#line 1705 "reflect.h2" +#line 1699 "reflect.h2" }; -#line 1708 "reflect.h2" +#line 1702 "reflect.h2" // // Parse and generation context. // @@ -722,33 +722,33 @@ class parse_context_group_state // Start a new alternative. public: auto next_alternative() & -> void; -#line 1728 "reflect.h2" +#line 1722 "reflect.h2" // Swap this state with the other one. NOLINTNEXTLINE(performance-noexcept-swap) public: auto swap(parse_context_group_state& t) & -> void; -#line 1735 "reflect.h2" +#line 1729 "reflect.h2" // Convert this state into a regex token. public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 1747 "reflect.h2" +#line 1741 "reflect.h2" // Add a token to the current matcher list. public: auto add(cpp2::impl::in token) & -> void; -#line 1752 "reflect.h2" +#line 1746 "reflect.h2" // True if current matcher list is empty. public: [[nodiscard]] auto empty() const& -> bool; -#line 1756 "reflect.h2" +#line 1750 "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 1770 "reflect.h2" +#line 1764 "reflect.h2" }; -#line 1773 "reflect.h2" +#line 1767 "reflect.h2" // State for the branch reset. Takes care of the group numbering. See '(|)'. // class parse_context_branch_reset_state @@ -761,25 +761,25 @@ class parse_context_branch_reset_state // Next group identifier. public: [[nodiscard]] auto next() & -> int; -#line 1791 "reflect.h2" +#line 1785 "reflect.h2" // Set next group identifier. public: auto set_next(cpp2::impl::in g) & -> void; -#line 1797 "reflect.h2" +#line 1791 "reflect.h2" // Start a new alternative branch. public: auto next_alternative() & -> void; -#line 1804 "reflect.h2" +#line 1798 "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 1811 "reflect.h2" +#line 1805 "reflect.h2" }; -#line 1814 "reflect.h2" +#line 1808 "reflect.h2" // Context during parsing of the regular expressions. // // Keeps track of the distributed group identifiers, current parsed group and branch resets. @@ -793,7 +793,7 @@ class parse_context private: parse_context_group_state cur_group_state {}; private: parse_context_branch_reset_state cur_branch_reset_state {}; -#line 1828 "reflect.h2" +#line 1822 "reflect.h2" public: std::map named_groups {}; private: error_func error_out; // TODO: Declaring std::function fails for cpp2. @@ -801,64 +801,64 @@ class parse_context public: explicit parse_context(cpp2::impl::in r, auto const& e); -#line 1839 "reflect.h2" +#line 1833 "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 1852 "reflect.h2" +#line 1846 "reflect.h2" // `old_state` argument needs to be from start group. public: [[nodiscard]] auto end_group(cpp2::impl::in old_state) & -> token_ptr; -#line 1860 "reflect.h2" +#line 1854 "reflect.h2" public: [[nodiscard]] auto get_modifiers() const& -> expression_flags; -#line 1864 "reflect.h2" +#line 1858 "reflect.h2" public: auto set_modifiers(cpp2::impl::in mod) & -> void; -#line 1868 "reflect.h2" +#line 1862 "reflect.h2" // Branch reset management functions // public: [[nodiscard]] auto branch_reset_new_state() & -> parse_context_branch_reset_state; -#line 1880 "reflect.h2" +#line 1874 "reflect.h2" public: auto branch_reset_restore_state(cpp2::impl::in old_state) & -> void; -#line 1887 "reflect.h2" +#line 1881 "reflect.h2" public: auto next_alternative() & -> void; -#line 1893 "reflect.h2" +#line 1887 "reflect.h2" // Regex token management // public: auto add_token(cpp2::impl::in token) & -> void; -#line 1899 "reflect.h2" +#line 1893 "reflect.h2" public: [[nodiscard]] auto has_token() const& -> bool; -#line 1903 "reflect.h2" +#line 1897 "reflect.h2" public: [[nodiscard]] auto pop_token() & -> token_ptr; -#line 1914 "reflect.h2" +#line 1908 "reflect.h2" public: [[nodiscard]] auto get_as_token() & -> token_ptr; -#line 1918 "reflect.h2" +#line 1912 "reflect.h2" // Group management // public: [[nodiscard]] auto get_cur_group() const& -> int; -#line 1924 "reflect.h2" +#line 1918 "reflect.h2" public: [[nodiscard]] auto next_group() & -> int; -#line 1928 "reflect.h2" +#line 1922 "reflect.h2" public: auto set_named_group(cpp2::impl::in name, cpp2::impl::in id) & -> void; -#line 1935 "reflect.h2" +#line 1929 "reflect.h2" public: [[nodiscard]] auto get_named_group(cpp2::impl::in name) const& -> int; -#line 1946 "reflect.h2" +#line 1940 "reflect.h2" // Position management functions // public: [[nodiscard]] auto current() const& -> char; @@ -866,51 +866,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 1990 "reflect.h2" +#line 1984 "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 2002 "reflect.h2" +#line 1996 "reflect.h2" public: [[nodiscard]] auto next() & -> auto; public: [[nodiscard]] auto next_in_class() & -> auto; public: [[nodiscard]] auto next_no_skip() & -> auto; public: [[nodiscard]] auto next_n(cpp2::impl::in n) & -> bool; -#line 2015 "reflect.h2" +#line 2009 "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 2038 "reflect.h2" +#line 2032 "reflect.h2" public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> auto; public: [[nodiscard]] auto grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> auto; public: [[nodiscard]] auto grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> auto; public: [[nodiscard]] auto grab_n(cpp2::impl::in n, cpp2::impl::out r) & -> bool; -#line 2055 "reflect.h2" +#line 2049 "reflect.h2" public: [[nodiscard]] auto grab_number() & -> std::string; -#line 2076 "reflect.h2" +#line 2070 "reflect.h2" private: [[nodiscard]] auto peek_impl(cpp2::impl::in in_class) const& -> char; -#line 2086 "reflect.h2" +#line 2080 "reflect.h2" public: [[nodiscard]] auto peek() const& -> auto; public: [[nodiscard]] auto peek_in_class() const& -> auto; -#line 2090 "reflect.h2" +#line 2084 "reflect.h2" // Parsing functions // public: [[nodiscard]] auto parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool; -#line 2146 "reflect.h2" +#line 2140 "reflect.h2" public: [[nodiscard]] auto parse_until(cpp2::impl::in term) & -> bool; -#line 2184 "reflect.h2" +#line 2178 "reflect.h2" public: [[nodiscard]] auto parse(cpp2::impl::in modifiers) & -> bool; -#line 2199 "reflect.h2" +#line 2193 "reflect.h2" // Misc functions public: [[nodiscard]] auto get_pos() const& -> auto; @@ -922,10 +922,10 @@ class parse_context public: auto operator=(parse_context const&) -> void = delete; -#line 2210 "reflect.h2" +#line 2204 "reflect.h2" }; -#line 2213 "reflect.h2" +#line 2207 "reflect.h2" // Context for one function generation. Generation of functions can be interleaved, // therefore we buffer the code for one function here. // @@ -935,16 +935,16 @@ class generation_function_context { public: auto add_tabs(cpp2::impl::in c) & -> void; -#line 2227 "reflect.h2" +#line 2221 "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 2230 "reflect.h2" +#line 2224 "reflect.h2" }; -#line 2233 "reflect.h2" +#line 2227 "reflect.h2" // Context for generating the state machine. class generation_context { @@ -964,68 +964,68 @@ class generation_context // Add code line. public: auto add(cpp2::impl::in s) & -> void; -#line 2255 "reflect.h2" +#line 2249 "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 2261 "reflect.h2" +#line 2255 "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 2270 "reflect.h2" +#line 2264 "reflect.h2" protected: auto start_func_named(cpp2::impl::in name) & -> void; -#line 2281 "reflect.h2" +#line 2275 "reflect.h2" protected: [[nodiscard]] auto start_func() & -> std::string; -#line 2288 "reflect.h2" +#line 2282 "reflect.h2" protected: auto end_func_statefull(cpp2::impl::in s) & -> void; -#line 2307 "reflect.h2" +#line 2301 "reflect.h2" // Generate the function for a token. public: [[nodiscard]] auto generate_func(cpp2::impl::in token) & -> std::string; -#line 2317 "reflect.h2" +#line 2311 "reflect.h2" // Generate the reset for a list of group identifiers. public: [[nodiscard]] auto generate_reset(cpp2::impl::in> groups) & -> std::string; -#line 2340 "reflect.h2" +#line 2334 "reflect.h2" // Name generation // protected: [[nodiscard]] auto gen_func_name() & -> std::string; -#line 2348 "reflect.h2" +#line 2342 "reflect.h2" public: [[nodiscard]] auto next_func_name() & -> std::string; -#line 2352 "reflect.h2" +#line 2346 "reflect.h2" protected: [[nodiscard]] auto gen_reset_func_name() & -> std::string; -#line 2358 "reflect.h2" +#line 2352 "reflect.h2" public: [[nodiscard]] auto gen_temp() & -> std::string; -#line 2364 "reflect.h2" +#line 2358 "reflect.h2" // Context management // public: [[nodiscard]] auto new_context() & -> generation_function_context*; -#line 2374 "reflect.h2" +#line 2368 "reflect.h2" public: auto finish_context() & -> void; -#line 2382 "reflect.h2" +#line 2376 "reflect.h2" // Misc functions // private: [[nodiscard]] auto get_current() & -> generation_function_context*; -#line 2388 "reflect.h2" +#line 2382 "reflect.h2" private: [[nodiscard]] auto get_base() & -> generation_function_context*; -#line 2392 "reflect.h2" +#line 2386 "reflect.h2" public: [[nodiscard]] auto get_entry_func() const& -> std::string; -#line 2396 "reflect.h2" +#line 2390 "reflect.h2" public: [[nodiscard]] auto create_named_group_lookup(cpp2::impl::in> named_groups) const& -> std::string; -#line 2420 "reflect.h2" +#line 2414 "reflect.h2" // Run the generation for the token. public: [[nodiscard]] auto run(cpp2::impl::in token) & -> std::string; public: generation_context() = default; @@ -1033,7 +1033,7 @@ class generation_context public: auto operator=(generation_context const&) -> void = delete; -#line 2426 "reflect.h2" +#line 2420 "reflect.h2" }; // Regex syntax: | Example: ab|ba @@ -1053,24 +1053,24 @@ class alternative_token public: auto operator=(alternative_token const&) -> void = delete; -#line 2445 "reflect.h2" +#line 2439 "reflect.h2" }; class alternative_token_gen : public regex_token { -#line 2451 "reflect.h2" +#line 2445 "reflect.h2" private: token_vec alternatives; public: explicit alternative_token_gen(cpp2::impl::in a); -#line 2458 "reflect.h2" +#line 2452 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 2475 "reflect.h2" +#line 2469 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; -#line 2482 "reflect.h2" +#line 2476 "reflect.h2" public: [[nodiscard]] static auto gen_string(cpp2::impl::in a) -> std::string; public: virtual ~alternative_token_gen() noexcept; @@ -1078,19 +1078,19 @@ class alternative_token_gen public: auto operator=(alternative_token_gen const&) -> void = delete; -#line 2494 "reflect.h2" +#line 2488 "reflect.h2" }; -#line 2497 "reflect.h2" +#line 2491 "reflect.h2" // Regex syntax: . // class any_token : public regex_token_check { -#line 2503 "reflect.h2" +#line 2497 "reflect.h2" public: explicit any_token(cpp2::impl::in single_line); -#line 2507 "reflect.h2" +#line 2501 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~any_token() noexcept; @@ -1098,37 +1098,37 @@ class any_token public: auto operator=(any_token const&) -> void = delete; -#line 2512 "reflect.h2" +#line 2506 "reflect.h2" }; -#line 2515 "reflect.h2" +#line 2509 "reflect.h2" // Regex syntax: a // class char_token : public regex_token { -#line 2521 "reflect.h2" +#line 2515 "reflect.h2" private: std::string token; private: bool ignore_case; public: explicit char_token(cpp2::impl::in t, cpp2::impl::in ignore_case_); -#line 2530 "reflect.h2" +#line 2524 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 2534 "reflect.h2" +#line 2528 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 2557 "reflect.h2" +#line 2551 "reflect.h2" public: auto gen_case_insensitive(cpp2::impl::in lower, cpp2::impl::in upper, generation_context& ctx) const& -> void; -#line 2578 "reflect.h2" +#line 2572 "reflect.h2" public: auto gen_case_sensitive(generation_context& ctx) const& -> void; -#line 2596 "reflect.h2" +#line 2590 "reflect.h2" public: [[nodiscard]] auto add_escapes(std::string str) const& -> std::string; -#line 2611 "reflect.h2" +#line 2605 "reflect.h2" public: auto append(char_token const& that) & -> void; public: virtual ~char_token() noexcept; @@ -1136,30 +1136,30 @@ class char_token public: auto operator=(char_token const&) -> void = delete; -#line 2615 "reflect.h2" +#line 2609 "reflect.h2" }; -#line 2618 "reflect.h2" +#line 2612 "reflect.h2" // Regex syntax: [] Example: [abcx-y[:digits:]] // class class_token : public regex_token { -#line 2624 "reflect.h2" +#line 2618 "reflect.h2" private: bool negate; private: bool case_insensitive; private: std::string class_str; public: explicit class_token(cpp2::impl::in negate_, cpp2::impl::in case_insensitive_, cpp2::impl::in class_str_, cpp2::impl::in str); -#line 2636 "reflect.h2" +#line 2630 "reflect.h2" // TODO: Rework class generation: Generate check functions for classes. public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 2762 "reflect.h2" +#line 2756 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 2767 "reflect.h2" +#line 2761 "reflect.h2" private: [[nodiscard]] static auto create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string; public: virtual ~class_token() noexcept; @@ -1167,20 +1167,20 @@ class class_token public: auto operator=(class_token const&) -> void = delete; -#line 2774 "reflect.h2" +#line 2768 "reflect.h2" }; -#line 2777 "reflect.h2" +#line 2771 "reflect.h2" // Regex syntax: \a or \n or \[ // [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr; -#line 2818 "reflect.h2" +#line 2812 "reflect.h2" // Regex syntax: \K Example: ab\Kcd // [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr; -#line 2829 "reflect.h2" +#line 2823 "reflect.h2" // Regex syntax: \ Example: \1 // \g{name_or_number} // \k{name_or_number} @@ -1190,16 +1190,16 @@ class class_token class group_ref_token : public regex_token { -#line 2839 "reflect.h2" +#line 2833 "reflect.h2" private: int id; private: bool case_insensitive; public: explicit group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in str); -#line 2849 "reflect.h2" +#line 2843 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 2950 "reflect.h2" +#line 2944 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; public: virtual ~group_ref_token() noexcept; @@ -1207,10 +1207,10 @@ class group_ref_token public: auto operator=(group_ref_token const&) -> void = delete; -#line 2953 "reflect.h2" +#line 2947 "reflect.h2" }; -#line 2956 "reflect.h2" +#line 2950 "reflect.h2" // Regex syntax: () Example: (abc) // (?:) (?i:abc) @@ -1224,22 +1224,22 @@ class group_ref_token class group_token : public regex_token { -#line 2970 "reflect.h2" +#line 2964 "reflect.h2" private: int number {-1}; private: token_ptr inner {nullptr}; public: [[nodiscard]] static auto parse_lookahead(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in positive) -> token_ptr; -#line 2987 "reflect.h2" +#line 2981 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 3124 "reflect.h2" +#line 3118 "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 3142 "reflect.h2" +#line 3136 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 3162 "reflect.h2" +#line 3156 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~group_token() noexcept; @@ -1248,25 +1248,25 @@ class group_token public: auto operator=(group_token const&) -> void = delete; -#line 3169 "reflect.h2" +#line 3163 "reflect.h2" }; -#line 3172 "reflect.h2" +#line 3166 "reflect.h2" // Regex syntax: \x or \x{} Example: \x{62} // [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr; -#line 3213 "reflect.h2" +#line 3207 "reflect.h2" // Regex syntax: $ Example: aa$ // [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr; -#line 3233 "reflect.h2" +#line 3227 "reflect.h2" // Regex syntax: ^ Example: ^aa // [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr; -#line 3249 "reflect.h2" +#line 3243 "reflect.h2" // Regex syntax: (?=) or (?!) or (*pla), etc. Example: (?=AA) // // Parsed in group_token. @@ -1274,16 +1274,16 @@ class group_token class lookahead_token : public regex_token { -#line 3257 "reflect.h2" +#line 3251 "reflect.h2" protected: bool positive; public: token_ptr inner {nullptr}; public: explicit lookahead_token(cpp2::impl::in positive_); -#line 3264 "reflect.h2" +#line 3258 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 3270 "reflect.h2" +#line 3264 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~lookahead_token() noexcept; @@ -1291,26 +1291,26 @@ class lookahead_token public: auto operator=(lookahead_token const&) -> void = delete; -#line 3273 "reflect.h2" +#line 3267 "reflect.h2" }; -#line 3276 "reflect.h2" +#line 3270 "reflect.h2" // Named character classes // [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr; -#line 3304 "reflect.h2" +#line 3298 "reflect.h2" // Regex syntax: \o{} Example: \o{142} // [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr; -#line 3332 "reflect.h2" +#line 3326 "reflect.h2" // Regex syntax: {min, max} Example: a{2,4} // class range_token : public regex_token { -#line 3338 "reflect.h2" +#line 3332 "reflect.h2" protected: int min_count {-1}; protected: int max_count {-1}; protected: int kind {range_flags::greedy}; @@ -1320,19 +1320,19 @@ class range_token public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; -#line 3418 "reflect.h2" +#line 3412 "reflect.h2" public: auto parse_modifier(parse_context& ctx) & -> void; -#line 3430 "reflect.h2" +#line 3424 "reflect.h2" public: [[nodiscard]] auto gen_mod_string() const& -> std::string; -#line 3443 "reflect.h2" +#line 3437 "reflect.h2" public: [[nodiscard]] auto gen_range_string() const& -> std::string; -#line 3462 "reflect.h2" +#line 3456 "reflect.h2" public: auto generate_code(generation_context& ctx) const -> void override; -#line 3473 "reflect.h2" +#line 3467 "reflect.h2" public: auto add_groups(std::set& groups) const -> void override; public: virtual ~range_token() noexcept; @@ -1340,16 +1340,16 @@ class range_token public: auto operator=(range_token const&) -> void = delete; -#line 3477 "reflect.h2" +#line 3471 "reflect.h2" }; -#line 3480 "reflect.h2" +#line 3474 "reflect.h2" // Regex syntax: *, +, or ? Example: aa* // class special_range_token : public range_token { -#line 3486 "reflect.h2" +#line 3480 "reflect.h2" public: [[nodiscard]] static auto parse(parse_context& ctx) -> token_ptr; public: virtual ~special_range_token() noexcept; @@ -1358,17 +1358,17 @@ class special_range_token public: auto operator=(special_range_token const&) -> void = delete; -#line 3516 "reflect.h2" +#line 3510 "reflect.h2" }; -#line 3519 "reflect.h2" +#line 3513 "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 3541 "reflect.h2" +#line 3535 "reflect.h2" //----------------------------------------------------------------------- // // Parser for regular expression. @@ -1389,24 +1389,24 @@ template class regex_generator public: explicit regex_generator(cpp2::impl::in r, Error_out const& e); -#line 3564 "reflect.h2" +#line 3558 "reflect.h2" public: [[nodiscard]] auto parse() & -> std::string; -#line 3599 "reflect.h2" +#line 3593 "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 3613 "reflect.h2" +#line 3607 "reflect.h2" }; template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string; -#line 3625 "reflect.h2" +#line 3619 "reflect.h2" auto regex_gen(meta::type_declaration& t) -> void; -#line 3680 "reflect.h2" +#line 3674 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -1417,7 +1417,7 @@ auto regex_gen(meta::type_declaration& t) -> void; auto const& error ) -> bool; -#line 3793 "reflect.h2" +#line 3787 "reflect.h2" } } @@ -2405,12 +2405,11 @@ auto hashable(meta::type_declaration& t) -> void CPP2_UFCS(require)(t, !(CPP2_UFCS(empty)(CPP2_UFCS(get_member_objects)(t))), "a hashable type must have at least one data member"); - std::string hash {" hash: (this) -> size_t ="}; - auto count {0}; + std::string hash {" hash: (this) -> size_t = {\n" + " ret: size_t = 0;"}; for ( - - auto const& o : CPP2_UFCS(get_member_objects)(t) ) { do + auto const& o : CPP2_UFCS(get_member_objects)(t) ) { cpp2::impl::deferred_init o_hash; if (CPP2_UFCS(name)(o) == "this") { @@ -2420,18 +2419,13 @@ auto hashable(meta::type_declaration& t) -> void o_hash.construct("std::hash<" + cpp2::to_string(CPP2_UFCS(type)(o)) + ">()(" + cpp2::to_string(CPP2_UFCS(name)(o)) + ")"); } - if (count == 0) { - hash += " " + cpp2::to_string(cpp2::move(o_hash.value())) + ""; - } - else { - hash += " ^ (" + cpp2::to_string(cpp2::move(o_hash.value())) + " << " + cpp2::to_string(count) + ")"; - } - } while (false); ++count; } + hash += "\n ret ^= " + cpp2::to_string(cpp2::move(o_hash.value())) + " + (ret << 6) + (ret >> 2);"; + } - CPP2_UFCS(add_member)(t, cpp2::move(hash) + ";"); + CPP2_UFCS(add_member)(t, cpp2::move(hash) + "\n return ret;\n }"); } -#line 874 "reflect.h2" +#line 868 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -2439,7 +2433,7 @@ auto hashable(meta::type_declaration& t) -> void // A regular type: copyable, plus has public default construction // and no protected or virtual functions // -#line 881 "reflect.h2" +#line 875 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -2468,28 +2462,28 @@ auto basic_value(meta::type_declaration& t) -> void // // Note: the ordering that should be encouraged as default gets the nice name // -#line 909 "reflect.h2" +#line 903 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 915 "reflect.h2" +#line 909 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(weakly_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 921 "reflect.h2" +#line 915 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void { CPP2_UFCS(partially_ordered)(t); CPP2_UFCS(basic_value)(t); } -#line 928 "reflect.h2" +#line 922 "reflect.h2" //----------------------------------------------------------------------- // // C.20: If you can avoid defining default operations, do @@ -2512,7 +2506,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void // // a type without declared copy/move/destructor functions // -#line 950 "reflect.h2" +#line 944 "reflect.h2" auto cpp1_rule_of_zero(meta::type_declaration& t) -> void { for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) @@ -2555,7 +2549,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 992 "reflect.h2" +#line 986 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { std::string ctor_params {}; @@ -2612,7 +2606,7 @@ value_member_info::value_member_info(auto const& name_, auto const& type_, auto , type{ type_ } , value{ value_ }{} -#line 1044 "reflect.h2" +#line 1038 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -2631,7 +2625,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 1067 "reflect.h2" +#line 1061 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -2656,7 +2650,7 @@ auto basic_enum( { std::string value{"-1"}; -#line 1090 "reflect.h2" +#line 1084 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -2698,7 +2692,7 @@ std::string value{"-1"}; } } -#line 1130 "reflect.h2" +#line 1124 "reflect.h2" if ((CPP2_UFCS(empty)(enumerators))) { CPP2_UFCS(error)(t, "an enumeration must contain at least one enumerator value"); return ; @@ -2749,7 +2743,7 @@ std::string value{"-1"}; } } -#line 1181 "reflect.h2" +#line 1175 "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' @@ -2799,7 +2793,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 1228 "reflect.h2" +#line 1222 "reflect.h2" { if (bitwise) { to_string_impl += ", separator: std::string_view ) -> std::string = { \n" @@ -2840,7 +2834,7 @@ std::string to_string_impl{" to_string_impl: (this, prefix: std::string_view" } } -#line 1267 "reflect.h2" +#line 1261 "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)) + "::\", \" | \" );"); @@ -2854,7 +2848,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ // Provide a 'from_string' function to parse strings into enumerators -#line 1278 "reflect.h2" +#line 1272 "reflect.h2" { std::string_view prefix {""}; std::string_view combine_op {"return"}; @@ -2876,7 +2870,7 @@ std::string from_string{" from_string: (s: std::string_view) -> " + cpp2::to_ { std::string_view else_{""}; -#line 1298 "reflect.h2" +#line 1292 "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(e.name) + "; }\n"; @@ -2884,7 +2878,7 @@ std::string_view else_{""}; } } -#line 1304 "reflect.h2" +#line 1298 "reflect.h2" if (bitwise) { from_string += " else { break outer; }\n" " }\n" @@ -2900,11 +2894,11 @@ std::string_view else_{""}; } } -#line 1318 "reflect.h2" +#line 1312 "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 1322 "reflect.h2" +#line 1316 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -2914,7 +2908,7 @@ std::string_view else_{""}; // // -- P0707R4, section 3 // -#line 1331 "reflect.h2" +#line 1325 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -2931,7 +2925,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1348 "reflect.h2" +#line 1342 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -2942,7 +2936,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void // // -- P0707R4, section 3 // -#line 1358 "reflect.h2" +#line 1352 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -2964,7 +2958,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1380 "reflect.h2" +#line 1374 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -2989,7 +2983,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 1404 "reflect.h2" +#line 1398 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -2998,7 +2992,7 @@ auto value{0}; // 1. Gather: All the user-written members, and find/compute the max size -#line 1411 "reflect.h2" +#line 1405 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -3028,7 +3022,7 @@ auto value{0}; } while (false); ++value; } } -#line 1439 "reflect.h2" +#line 1433 "reflect.h2" std::string discriminator_type {}; if (cpp2::impl::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -3043,7 +3037,7 @@ auto value{0}; discriminator_type = "i64"; }}} -#line 1454 "reflect.h2" +#line 1448 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -3052,7 +3046,7 @@ std::string storage{" _storage: cpp2::aligned_storage t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; @@ -3257,7 +3251,7 @@ return 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 1561 "reflect.h2" +#line 1555 "reflect.h2" //----------------------------------------------------------------------- // // regex - creates regular expressions from members @@ -3273,11 +3267,11 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // ``` // -#line 1577 "reflect.h2" +#line 1571 "reflect.h2" // Possible modifiers for a regular expression. // -#line 1581 "reflect.h2" +#line 1575 "reflect.h2" // mod: i // mod: m // mod: s @@ -3285,106 +3279,106 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov // mod: x // mod: xx -#line 1590 "reflect.h2" +#line 1584 "reflect.h2" // Tokens for regular expressions. // // Basic class for a regex token. // -#line 1599 "reflect.h2" +#line 1593 "reflect.h2" regex_token::regex_token(cpp2::impl::in str) : string_rep{ str }{ -#line 1601 "reflect.h2" +#line 1595 "reflect.h2" } -#line 1603 "reflect.h2" +#line 1597 "reflect.h2" regex_token::regex_token() : string_rep{ "" }{ -#line 1605 "reflect.h2" +#line 1599 "reflect.h2" } //parse: (inout ctx: parse_context) -> token_ptr; // Generate the matching code. -#line 1610 "reflect.h2" +#line 1604 "reflect.h2" auto regex_token::add_groups([[maybe_unused]] std::set& unnamed_param_2) const -> void{}// Adds all group indices to the set. -#line 1611 "reflect.h2" +#line 1605 "reflect.h2" [[nodiscard]] auto regex_token::to_string() const& -> std::string{return string_rep; }// Create a string representation. -#line 1612 "reflect.h2" +#line 1606 "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 1627 "reflect.h2" +#line 1621 "reflect.h2" regex_token_check::regex_token_check(cpp2::impl::in str, cpp2::impl::in check_) : regex_token{ str } , check{ check_ }{ -#line 1630 "reflect.h2" +#line 1624 "reflect.h2" } -#line 1632 "reflect.h2" +#line 1626 "reflect.h2" auto regex_token_check::generate_code(generation_context& ctx) const -> void{ ctx.add_check(check + "(" + ctx.match_parameters() + ")"); } regex_token_check::~regex_token_check() noexcept{} -#line 1646 "reflect.h2" +#line 1640 "reflect.h2" regex_token_code::regex_token_code(cpp2::impl::in str, cpp2::impl::in code_) : regex_token{ str } , code{ code_ }{ -#line 1649 "reflect.h2" +#line 1643 "reflect.h2" } -#line 1651 "reflect.h2" +#line 1645 "reflect.h2" auto regex_token_code::generate_code(generation_context& ctx) const -> void{ ctx.add(code); } regex_token_code::~regex_token_code() noexcept{} -#line 1663 "reflect.h2" +#line 1657 "reflect.h2" regex_token_empty::regex_token_empty(cpp2::impl::in str) : regex_token{ str }{ -#line 1665 "reflect.h2" +#line 1659 "reflect.h2" } -#line 1667 "reflect.h2" +#line 1661 "reflect.h2" auto regex_token_empty::generate_code([[maybe_unused]] generation_context& unnamed_param_2) const -> void{ // Nothing. } regex_token_empty::~regex_token_empty() noexcept{} -#line 1681 "reflect.h2" +#line 1675 "reflect.h2" regex_token_list::regex_token_list(cpp2::impl::in t) : regex_token{ gen_string(t) } , tokens{ t }{ -#line 1684 "reflect.h2" +#line 1678 "reflect.h2" } -#line 1686 "reflect.h2" +#line 1680 "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 1692 "reflect.h2" +#line 1686 "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 1698 "reflect.h2" +#line 1692 "reflect.h2" [[nodiscard]] auto regex_token_list::gen_string(cpp2::impl::in vec) -> std::string{ std::string r {""}; for ( auto const& token : vec ) { @@ -3395,7 +3389,7 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov regex_token_list::~regex_token_list() noexcept{} -#line 1721 "reflect.h2" +#line 1715 "reflect.h2" auto parse_context_group_state::next_alternative() & -> void{ token_vec new_list {}; std::swap(new_list, cur_match_list); @@ -3403,14 +3397,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 1729 "reflect.h2" +#line 1723 "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 1736 "reflect.h2" +#line 1730 "reflect.h2" [[nodiscard]] auto parse_context_group_state::get_as_token() & -> token_ptr{ if (alternate_match_lists.empty()) { post_process_list(cur_match_list); @@ -3422,15 +3416,15 @@ std::string str {s}; return from_string(cpp2::string_util::replace_all(cpp2::mov } } -#line 1748 "reflect.h2" +#line 1742 "reflect.h2" auto parse_context_group_state::add(cpp2::impl::in token) & -> void{ cur_match_list.push_back(token); } -#line 1753 "reflect.h2" +#line 1747 "reflect.h2" [[nodiscard]] auto parse_context_group_state::empty() const& -> bool { return cur_match_list.empty(); } -#line 1757 "reflect.h2" +#line 1751 "reflect.h2" auto parse_context_group_state::post_process_list(token_vec& list) -> void{ // Merge all characters auto merge_pos {list.begin()}; @@ -3451,7 +3445,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 1783 "reflect.h2" +#line 1777 "reflect.h2" [[nodiscard]] auto parse_context_branch_reset_state::next() & -> int{ auto g {cur_group}; cur_group += 1; @@ -3460,20 +3454,20 @@ parse_context_group_state::parse_context_group_state(){} return g; } -#line 1792 "reflect.h2" +#line 1786 "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 1798 "reflect.h2" +#line 1792 "reflect.h2" auto parse_context_branch_reset_state::next_alternative() & -> void{ if (is_active) { cur_group = from; } } -#line 1805 "reflect.h2" +#line 1799 "reflect.h2" auto parse_context_branch_reset_state::set_active_reset(cpp2::impl::in restart) & -> void{ is_active = true; cur_group = restart; @@ -3488,16 +3482,16 @@ parse_context_group_state::parse_context_group_state(){} , from{ from_ }{} parse_context_branch_reset_state::parse_context_branch_reset_state(){} -#line 1833 "reflect.h2" +#line 1827 "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 1837 "reflect.h2" +#line 1831 "reflect.h2" } -#line 1843 "reflect.h2" +#line 1837 "reflect.h2" [[nodiscard]] auto parse_context::start_group() & -> parse_context_group_state { parse_context_group_state old_state {}; @@ -3507,7 +3501,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 1853 "reflect.h2" +#line 1847 "reflect.h2" [[nodiscard]] auto parse_context::end_group(cpp2::impl::in old_state) & -> token_ptr { auto inner {cur_group_state.get_as_token()}; @@ -3515,17 +3509,17 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return inner; } -#line 1860 "reflect.h2" +#line 1854 "reflect.h2" [[nodiscard]] auto parse_context::get_modifiers() const& -> expression_flags{ return cur_group_state.modifiers; } -#line 1864 "reflect.h2" +#line 1858 "reflect.h2" auto parse_context::set_modifiers(cpp2::impl::in mod) & -> void{ cur_group_state.modifiers = mod; } -#line 1871 "reflect.h2" +#line 1865 "reflect.h2" [[nodiscard]] auto parse_context::branch_reset_new_state() & -> parse_context_branch_reset_state { parse_context_branch_reset_state old_state {}; @@ -3535,7 +3529,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return old_state; } -#line 1880 "reflect.h2" +#line 1874 "reflect.h2" auto parse_context::branch_reset_restore_state(cpp2::impl::in old_state) & -> void { auto max_group {cur_branch_reset_state.max_group}; @@ -3543,24 +3537,24 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} cur_branch_reset_state.set_next(cpp2::move(max_group)); } -#line 1887 "reflect.h2" +#line 1881 "reflect.h2" auto parse_context::next_alternative() & -> void { cur_group_state.next_alternative(); cur_branch_reset_state.next_alternative(); } -#line 1895 "reflect.h2" +#line 1889 "reflect.h2" auto parse_context::add_token(cpp2::impl::in token) & -> void{ cur_group_state.add(token); } -#line 1899 "reflect.h2" +#line 1893 "reflect.h2" [[nodiscard]] auto parse_context::has_token() const& -> bool{ return !(cur_group_state.empty()); } -#line 1903 "reflect.h2" +#line 1897 "reflect.h2" [[nodiscard]] auto parse_context::pop_token() & -> token_ptr { token_ptr r {nullptr}; @@ -3572,22 +3566,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 1914 "reflect.h2" +#line 1908 "reflect.h2" [[nodiscard]] auto parse_context::get_as_token() & -> token_ptr{ return root; } -#line 1920 "reflect.h2" +#line 1914 "reflect.h2" [[nodiscard]] auto parse_context::get_cur_group() const& -> int{ return cur_branch_reset_state.cur_group; } -#line 1924 "reflect.h2" +#line 1918 "reflect.h2" [[nodiscard]] auto parse_context::next_group() & -> int{ return cur_branch_reset_state.next(); } -#line 1928 "reflect.h2" +#line 1922 "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. @@ -3595,7 +3589,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 1935 "reflect.h2" +#line 1929 "reflect.h2" [[nodiscard]] auto parse_context::get_named_group(cpp2::impl::in name) const& -> int { auto iter {named_groups.find(name)}; @@ -3607,10 +3601,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 1948 "reflect.h2" +#line 1942 "reflect.h2" [[nodiscard]] auto parse_context::current() const& -> char{return CPP2_ASSERT_IN_BOUNDS(regex, pos); } -#line 1951 "reflect.h2" +#line 1945 "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}; @@ -3650,7 +3644,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cur; } -#line 1991 "reflect.h2" +#line 1985 "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); @@ -3662,14 +3656,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 2002 "reflect.h2" +#line 1996 "reflect.h2" [[nodiscard]] auto parse_context::next() & -> auto { return next_impl(false, false); } -#line 2003 "reflect.h2" +#line 1997 "reflect.h2" [[nodiscard]] auto parse_context::next_in_class() & -> auto { return next_impl(true, false); } -#line 2004 "reflect.h2" +#line 1998 "reflect.h2" [[nodiscard]] auto parse_context::next_no_skip() & -> auto { return next_impl(false, true); } -#line 2006 "reflect.h2" +#line 2000 "reflect.h2" [[nodiscard]] auto parse_context::next_n(cpp2::impl::in n) & -> bool{ auto r {true}; auto cur {0}; @@ -3679,10 +3673,10 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 2015 "reflect.h2" +#line 2009 "reflect.h2" [[nodiscard]] auto parse_context::has_next() const& -> bool{return cpp2::impl::cmp_less(pos,regex.size()); } -#line 2017 "reflect.h2" +#line 2011 "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) @@ -3704,14 +3698,14 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 2038 "reflect.h2" +#line 2032 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> auto { return grab_until_impl(e, cpp2::impl::out(&r), false); } -#line 2039 "reflect.h2" +#line 2033 "reflect.h2" [[nodiscard]] auto parse_context::grab_until(cpp2::impl::in e, cpp2::impl::out r) & -> auto { return grab_until_impl(std::string(1, e), cpp2::impl::out(&r), false); } -#line 2040 "reflect.h2" +#line 2034 "reflect.h2" [[nodiscard]] auto parse_context::grab_until_one_of(cpp2::impl::in e, cpp2::impl::out r) & -> auto { return grab_until_impl(e, cpp2::impl::out(&r), true); } -#line 2042 "reflect.h2" +#line 2036 "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())) { @@ -3725,7 +3719,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 2055 "reflect.h2" +#line 2049 "reflect.h2" [[nodiscard]] auto parse_context::grab_number() & -> std::string { auto start {pos}; @@ -3747,7 +3741,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return cpp2::move(r.value()); } -#line 2076 "reflect.h2" +#line 2070 "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())) { @@ -3758,12 +3752,12 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 2086 "reflect.h2" +#line 2080 "reflect.h2" [[nodiscard]] auto parse_context::peek() const& -> auto { return peek_impl(false); } -#line 2087 "reflect.h2" +#line 2081 "reflect.h2" [[nodiscard]] auto parse_context::peek_in_class() const& -> auto { return peek_impl(true); } -#line 2092 "reflect.h2" +#line 2086 "reflect.h2" [[nodiscard]] auto parse_context::parser_group_modifiers(cpp2::impl::in change_str, expression_flags& parser_modifiers) & -> bool { auto is_negative {false}; @@ -3818,7 +3812,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 2146 "reflect.h2" +#line 2140 "reflect.h2" [[nodiscard]] auto parse_context::parse_until(cpp2::impl::in term) & -> bool{ token_ptr cur_token {}; @@ -3857,7 +3851,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return true; } -#line 2184 "reflect.h2" +#line 2178 "reflect.h2" [[nodiscard]] auto parse_context::parse(cpp2::impl::in modifiers) & -> bool { @@ -3873,21 +3867,21 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} return r; } -#line 2201 "reflect.h2" +#line 2195 "reflect.h2" [[nodiscard]] auto parse_context::get_pos() const& -> auto { return pos; } -#line 2202 "reflect.h2" +#line 2196 "reflect.h2" [[nodiscard]] auto parse_context::get_range(cpp2::impl::in start, cpp2::impl::in end) const& -> auto { return std::string(regex.substr(start, end - start + 1)); } -#line 2203 "reflect.h2" +#line 2197 "reflect.h2" [[nodiscard]] auto parse_context::valid() const& -> bool{return has_next() && !(has_error); } -#line 2205 "reflect.h2" +#line 2199 "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 2220 "reflect.h2" +#line 2214 "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 ) { @@ -3895,7 +3889,7 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} } } -#line 2227 "reflect.h2" +#line 2221 "reflect.h2" auto generation_function_context::remove_tabs(cpp2::impl::in c) & -> void{ tabs = tabs.substr(0, (cpp2::impl::as_(c)) * 2); } @@ -3905,22 +3899,22 @@ parse_context_branch_reset_state::parse_context_branch_reset_state(){} , tabs{ tabs_ }{} generation_function_context::generation_function_context(){} -#line 2245 "reflect.h2" +#line 2239 "reflect.h2" [[nodiscard]] auto generation_context::match_parameters() const& -> std::string{return "r.pos, ctx"; } -#line 2250 "reflect.h2" +#line 2244 "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 2256 "reflect.h2" +#line 2250 "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 2262 "reflect.h2" +#line 2256 "reflect.h2" auto generation_context::add_statefull(cpp2::impl::in next_func, cpp2::impl::in check) & -> void { end_func_statefull(check); @@ -3929,7 +3923,7 @@ generation_function_context::generation_function_context(){} start_func_named(cpp2::move(name)); } -#line 2270 "reflect.h2" +#line 2264 "reflect.h2" auto generation_context::start_func_named(cpp2::impl::in name) & -> void { auto cur {new_context()}; @@ -3941,7 +3935,7 @@ generation_function_context::generation_function_context(){} (*cpp2::impl::assert_not_null(cpp2::move(cur))).add_tabs(3); } -#line 2281 "reflect.h2" +#line 2275 "reflect.h2" [[nodiscard]] auto generation_context::start_func() & -> std::string { auto name {gen_func_name()}; @@ -3949,7 +3943,7 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 2288 "reflect.h2" +#line 2282 "reflect.h2" auto generation_context::end_func_statefull(cpp2::impl::in s) & -> void { auto cur {get_current()}; @@ -3969,7 +3963,7 @@ generation_function_context::generation_function_context(){} finish_context(); } -#line 2308 "reflect.h2" +#line 2302 "reflect.h2" [[nodiscard]] auto generation_context::generate_func(cpp2::impl::in token) & -> std::string { auto name {start_func()}; @@ -3979,7 +3973,7 @@ generation_function_context::generation_function_context(){} return name; } -#line 2318 "reflect.h2" +#line 2312 "reflect.h2" [[nodiscard]] auto generation_context::generate_reset(cpp2::impl::in> groups) & -> std::string { if (groups.empty()) { @@ -4002,33 +3996,33 @@ generation_function_context::generation_function_context(){} return cpp2::move(name) + "()"; } -#line 2342 "reflect.h2" +#line 2336 "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 2348 "reflect.h2" +#line 2342 "reflect.h2" [[nodiscard]] auto generation_context::next_func_name() & -> std::string{ return gen_func_name() + "()"; } -#line 2352 "reflect.h2" +#line 2346 "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 2358 "reflect.h2" +#line 2352 "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 2366 "reflect.h2" +#line 2360 "reflect.h2" [[nodiscard]] auto generation_context::new_context() & -> generation_function_context*{ gen_stack.push_back(generation_function_context()); auto cur {get_current()}; @@ -4037,7 +4031,7 @@ generation_function_context::generation_function_context(){} return cur; } -#line 2374 "reflect.h2" +#line 2368 "reflect.h2" auto generation_context::finish_context() & -> void{ auto cur {get_current()}; auto base {get_base()}; @@ -4046,22 +4040,22 @@ generation_function_context::generation_function_context(){} gen_stack.pop_back(); } -#line 2384 "reflect.h2" +#line 2378 "reflect.h2" [[nodiscard]] auto generation_context::get_current() & -> generation_function_context*{ return &gen_stack.back(); } -#line 2388 "reflect.h2" +#line 2382 "reflect.h2" [[nodiscard]] auto generation_context::get_base() & -> generation_function_context*{ return &CPP2_ASSERT_IN_BOUNDS_LITERAL(gen_stack, 0); } -#line 2392 "reflect.h2" +#line 2386 "reflect.h2" [[nodiscard]] auto generation_context::get_entry_func() const& -> std::string{ return entry_func; } -#line 2396 "reflect.h2" +#line 2390 "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"}; @@ -4085,18 +4079,18 @@ generation_function_context::generation_function_context(){} return res; } -#line 2421 "reflect.h2" +#line 2415 "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 2436 "reflect.h2" +#line 2430 "reflect.h2" alternative_token::alternative_token() : regex_token_empty{ "" }{} -#line 2438 "reflect.h2" +#line 2432 "reflect.h2" [[nodiscard]] auto alternative_token::parse(parse_context& ctx) -> token_ptr{ if (ctx.current() != '|') {return nullptr; } @@ -4107,15 +4101,15 @@ generation_function_context::generation_function_context(){} alternative_token::~alternative_token() noexcept{} -#line 2453 "reflect.h2" +#line 2447 "reflect.h2" alternative_token_gen::alternative_token_gen(cpp2::impl::in a) : regex_token{ gen_string(a) } , alternatives{ a }{ -#line 2456 "reflect.h2" +#line 2450 "reflect.h2" } -#line 2458 "reflect.h2" +#line 2452 "reflect.h2" auto alternative_token_gen::generate_code(generation_context& ctx) const -> void { std::string functions {""}; @@ -4133,7 +4127,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 2475 "reflect.h2" +#line 2469 "reflect.h2" auto alternative_token_gen::add_groups(std::set& groups) const -> void { for ( auto const& cur : alternatives ) { @@ -4141,7 +4135,7 @@ generation_function_context::generation_function_context(){} } } -#line 2482 "reflect.h2" +#line 2476 "reflect.h2" [[nodiscard]] auto alternative_token_gen::gen_string(cpp2::impl::in a) -> std::string { std::string r {""}; @@ -4157,14 +4151,14 @@ generation_function_context::generation_function_context(){} alternative_token_gen::~alternative_token_gen() noexcept{} -#line 2503 "reflect.h2" +#line 2497 "reflect.h2" any_token::any_token(cpp2::impl::in single_line) : regex_token_check{ ".", "any_token_matcher" }{ -#line 2505 "reflect.h2" +#line 2499 "reflect.h2" } -#line 2507 "reflect.h2" +#line 2501 "reflect.h2" [[nodiscard]] auto any_token::parse(parse_context& ctx) -> token_ptr{ if ('.' != ctx.current()) {return nullptr; } @@ -4173,21 +4167,21 @@ generation_function_context::generation_function_context(){} any_token::~any_token() noexcept{} -#line 2524 "reflect.h2" +#line 2518 "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 2528 "reflect.h2" +#line 2522 "reflect.h2" } -#line 2530 "reflect.h2" +#line 2524 "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 2534 "reflect.h2" +#line 2528 "reflect.h2" auto char_token::generate_code(generation_context& ctx) const -> void { if (ignore_case) { @@ -4196,14 +4190,14 @@ generation_function_context::generation_function_context(){} { size_t i{0}; -#line 2540 "reflect.h2" +#line 2534 "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 2545 "reflect.h2" +#line 2539 "reflect.h2" if (upper != lower) { gen_case_insensitive(cpp2::move(lower), cpp2::move(upper), ctx); } @@ -4216,7 +4210,7 @@ size_t i{0}; } } -#line 2557 "reflect.h2" +#line 2551 "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()) + ""}; @@ -4238,7 +4232,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 2578 "reflect.h2" +#line 2572 "reflect.h2" auto char_token::gen_case_sensitive(generation_context& ctx) const& -> void { std::string name {"str_" + cpp2::to_string(ctx.gen_temp()) + ""}; @@ -4257,7 +4251,7 @@ size_t i{0}; ctx.add("else { break; }"); } -#line 2596 "reflect.h2" +#line 2590 "reflect.h2" [[nodiscard]] auto char_token::add_escapes(std::string str) const& -> std::string { str = string_util::replace_all(str, "\\", "\\\\"); @@ -4273,7 +4267,7 @@ size_t i{0}; return cpp2::move(str); } -#line 2611 "reflect.h2" +#line 2605 "reflect.h2" auto char_token::append(char_token const& that) & -> void{ (*this).token += that.token; (*this).string_rep += that.string_rep; @@ -4281,19 +4275,19 @@ size_t i{0}; char_token::~char_token() noexcept{} -#line 2628 "reflect.h2" +#line 2622 "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 2629 "reflect.h2" +#line 2623 "reflect.h2" { -#line 2634 "reflect.h2" +#line 2628 "reflect.h2" } -#line 2637 "reflect.h2" +#line 2631 "reflect.h2" [[nodiscard]] auto class_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '[') {return nullptr; } @@ -4419,13 +4413,13 @@ size_t i{0}; ); } -#line 2762 "reflect.h2" +#line 2756 "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 2767 "reflect.h2" +#line 2761 "reflect.h2" [[nodiscard]] auto class_token::create_matcher(cpp2::impl::in name, cpp2::impl::in template_arguments) -> std::string { auto sep {", "}; @@ -4436,12 +4430,12 @@ size_t i{0}; class_token::~class_token() noexcept{} -#line 2779 "reflect.h2" +#line 2773 "reflect.h2" [[nodiscard]] auto escape_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } -#line 2784 "reflect.h2" +#line 2778 "reflect.h2" if (std::string::npos == std::string("afenrt^.[]()*{}?+|\\").find(ctx.peek())) { return nullptr; } @@ -4475,7 +4469,7 @@ size_t i{0}; } -#line 2820 "reflect.h2" +#line 2814 "reflect.h2" [[nodiscard]] auto global_group_reset_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'K'))) {return nullptr; } @@ -4484,18 +4478,18 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, "\\K", "ctx..set_group_start(0, r.pos);"); } -#line 2842 "reflect.h2" +#line 2836 "reflect.h2" group_ref_token::group_ref_token(cpp2::impl::in id_, cpp2::impl::in case_insensitive_, cpp2::impl::in str) : regex_token{ str } , id{ id_ } , case_insensitive{ case_insensitive_ } -#line 2843 "reflect.h2" +#line 2837 "reflect.h2" { -#line 2847 "reflect.h2" +#line 2841 "reflect.h2" } -#line 2849 "reflect.h2" +#line 2843 "reflect.h2" [[nodiscard]] auto group_ref_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -4597,14 +4591,14 @@ size_t i{0}; return CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared, cpp2::move(group_id), ctx.get_modifiers().has(expression_flags::case_insensitive), cpp2::move(str)); } -#line 2950 "reflect.h2" +#line 2944 "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 2973 "reflect.h2" +#line 2967 "reflect.h2" [[nodiscard]] auto group_token::parse_lookahead(parse_context& ctx, cpp2::impl::in syntax, cpp2::impl::in positive) -> token_ptr { static_cast(ctx.next());// Skip last token defining the syntax @@ -4619,7 +4613,7 @@ size_t i{0}; return r; } -#line 2987 "reflect.h2" +#line 2981 "reflect.h2" [[nodiscard]] auto group_token::parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '(') {return nullptr; } @@ -4757,7 +4751,7 @@ size_t i{0}; } } -#line 3124 "reflect.h2" +#line 3118 "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 {"("}; @@ -4776,7 +4770,7 @@ size_t i{0}; return cpp2::move(start) + (*cpp2::impl::assert_not_null(inner_)).to_string() + ")"; } -#line 3142 "reflect.h2" +#line 3136 "reflect.h2" auto group_token::generate_code(generation_context& ctx) const -> void { if (-1 != number) { @@ -4797,7 +4791,7 @@ size_t i{0}; } } -#line 3162 "reflect.h2" +#line 3156 "reflect.h2" auto group_token::add_groups(std::set& groups) const -> void { (*cpp2::impl::assert_not_null(inner)).add_groups(groups); @@ -4808,7 +4802,7 @@ size_t i{0}; group_token::~group_token() noexcept{} -#line 3174 "reflect.h2" +#line 3168 "reflect.h2" [[nodiscard]] auto hexadecimal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'x'))) {return nullptr; } @@ -4847,7 +4841,7 @@ size_t i{0}; return r; } -#line 3215 "reflect.h2" +#line 3209 "reflect.h2" [[nodiscard]] auto line_end_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() == '$' || (ctx.current() == '\\' && ctx.peek() == '$')) { @@ -4865,7 +4859,7 @@ size_t i{0}; }} } -#line 3235 "reflect.h2" +#line 3229 "reflect.h2" [[nodiscard]] auto line_start_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '^' && !((ctx.current() == '\\' && ctx.peek() == 'A'))) {return nullptr; } @@ -4879,29 +4873,29 @@ size_t i{0}; } } -#line 3260 "reflect.h2" +#line 3254 "reflect.h2" lookahead_token::lookahead_token(cpp2::impl::in positive_) : regex_token{ "" } , positive{ positive_ }{ -#line 3262 "reflect.h2" +#line 3256 "reflect.h2" } -#line 3264 "reflect.h2" +#line 3258 "reflect.h2" auto lookahead_token::generate_code(generation_context& ctx) const -> void{ auto inner_name {ctx.generate_func(inner)}; ctx.add_check("lookahead_token_matcher(" + cpp2::to_string(ctx.match_parameters()) + ", " + cpp2::to_string(cpp2::move(inner_name)) + ")"); } -#line 3270 "reflect.h2" +#line 3264 "reflect.h2" auto lookahead_token::add_groups(std::set& groups) const -> void{ (*cpp2::impl::assert_not_null(inner)).add_groups(groups); } lookahead_token::~lookahead_token() noexcept{} -#line 3278 "reflect.h2" +#line 3272 "reflect.h2" [[nodiscard]] auto named_class_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -4927,7 +4921,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 3306 "reflect.h2" +#line 3300 "reflect.h2" [[nodiscard]] auto octal_token_parse(parse_context& ctx) -> token_ptr { if (!((ctx.current() == '\\' && ctx.peek() == 'o'))) {return nullptr; } @@ -4953,11 +4947,11 @@ size_t i{0}; return r; } -#line 3343 "reflect.h2" +#line 3337 "reflect.h2" range_token::range_token() : regex_token{ "" }{} -#line 3345 "reflect.h2" +#line 3339 "reflect.h2" [[nodiscard]] auto range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -5031,7 +5025,7 @@ size_t i{0}; return nullptr; } -#line 3418 "reflect.h2" +#line 3412 "reflect.h2" auto range_token::parse_modifier(parse_context& ctx) & -> void { if (ctx.peek() == '?') { @@ -5044,7 +5038,7 @@ size_t i{0}; }} } -#line 3430 "reflect.h2" +#line 3424 "reflect.h2" [[nodiscard]] auto range_token::gen_mod_string() const& -> std::string { if (kind == range_flags::not_greedy) { @@ -5058,7 +5052,7 @@ size_t i{0}; }} } -#line 3443 "reflect.h2" +#line 3437 "reflect.h2" [[nodiscard]] auto range_token::gen_range_string() const& -> std::string { std::string r {""}; @@ -5078,7 +5072,7 @@ size_t i{0}; return r; } -#line 3462 "reflect.h2" +#line 3456 "reflect.h2" auto range_token::generate_code(generation_context& ctx) const -> void { auto inner_name {ctx.generate_func(inner_token)}; @@ -5090,14 +5084,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 3473 "reflect.h2" +#line 3467 "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 3486 "reflect.h2" +#line 3480 "reflect.h2" [[nodiscard]] auto special_range_token::parse(parse_context& ctx) -> token_ptr { auto r {CPP2_UFCS_TEMPLATE(cpp2_new)(cpp2::shared)}; @@ -5121,7 +5115,7 @@ size_t i{0}; if (!(ctx.has_token())) {return ctx.error("'" + cpp2::to_string(ctx.current()) + "' without previous element."); } -#line 3510 "reflect.h2" +#line 3504 "reflect.h2" (*cpp2::impl::assert_not_null(r)).parse_modifier(ctx); (*cpp2::impl::assert_not_null(r)).inner_token = ctx.pop_token(); @@ -5131,7 +5125,7 @@ size_t i{0}; special_range_token::~special_range_token() noexcept{} -#line 3523 "reflect.h2" +#line 3517 "reflect.h2" [[nodiscard]] auto word_boundary_token_parse(parse_context& ctx) -> token_ptr { if (ctx.current() != '\\') {return nullptr; } @@ -5149,15 +5143,15 @@ size_t i{0}; }} } -#line 3559 "reflect.h2" +#line 3553 "reflect.h2" template regex_generator::regex_generator(cpp2::impl::in r, Error_out const& e) : regex{ r } , error_out{ e }{ -#line 3562 "reflect.h2" +#line 3556 "reflect.h2" } -#line 3564 "reflect.h2" +#line 3558 "reflect.h2" template [[nodiscard]] auto regex_generator::parse() & -> std::string { // Extract modifiers and adapt regex. @@ -5193,7 +5187,7 @@ size_t i{0}; return source; } -#line 3599 "reflect.h2" +#line 3593 "reflect.h2" template auto regex_generator::extract_modifiers() & -> void { if (regex.find_first_of("'/") == 0) { @@ -5209,7 +5203,7 @@ size_t i{0}; } } -#line 3615 "reflect.h2" +#line 3609 "reflect.h2" template [[nodiscard]] auto generate_regex(cpp2::impl::in regex, Err const& err) -> std::string { regex_generator parser {regex, err}; @@ -5218,7 +5212,7 @@ template [[nodiscard]] auto generate_regex(cpp2::impl::in void { auto has_default {false}; @@ -5273,7 +5267,7 @@ auto regex_gen(meta::type_declaration& t) -> void CPP2_UFCS(add_runtime_support_include)(t, "cpp2regex.h"); } -#line 3684 "reflect.h2" +#line 3678 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -5382,7 +5376,7 @@ auto regex_gen(meta::type_declaration& t) -> void return true; } -#line 3793 "reflect.h2" +#line 3787 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 60fe4ce84..ff31c63cb 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -844,11 +844,10 @@ hashable: (inout t: meta::type_declaration) = t.require( !t.get_member_objects().empty(), "a hashable type must have at least one data member"); - hash: std::string = " hash: (this) -> size_t ="; - count := 0; + hash: std::string = " hash: (this) -> size_t = {\n" + " ret: size_t = 0;"; for t.get_member_objects() - next count++ do (o) { o_hash: std::string; @@ -859,15 +858,10 @@ hashable: (inout t: meta::type_declaration) = o_hash = "std::hash<(o.type())$>()((o.name())$)"; } - if count == 0 { - hash += " (o_hash)$"; - } - else { - hash += " ^ ((o_hash)$ << (count)$)"; - } + hash += "\n ret ^= (o_hash)$ + (ret << 6) + (ret >> 2);"; } - t.add_member(hash + ";"); + t.add_member(hash + "\n return ret;\n }"); }