From cf88bd1cc71c85cb86210db7fa654722627b6f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Tue, 14 Nov 2023 10:36:47 -0400 Subject: [PATCH 01/10] feat(reflect): add `function_declaration::get_parameters` --- source/parse.h | 10 +++ source/reflect.h | 207 ++++++++++++++++++++++++---------------------- source/reflect.h2 | 51 +++++++----- 3 files changed, 149 insertions(+), 119 deletions(-) diff --git a/source/parse.h b/source/parse.h index 3fdd54d735..39893e6f2e 100644 --- a/source/parse.h +++ b/source/parse.h @@ -3383,6 +3383,16 @@ struct declaration_node return false; } + auto get_function_parameters() + -> std::span> + { + if (!is_function()) { + return {}; + } + // else + return std::get(type)->parameters->parameters; + } + auto unnamed_return_type_to_string() const -> std::string { diff --git a/source/reflect.h b/source/reflect.h index e3d75c7434..0963ebcea3 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -27,19 +27,19 @@ class declaration; #line 301 "reflect.h2" class function_declaration; -#line 359 "reflect.h2" +#line 368 "reflect.h2" class object_declaration; -#line 395 "reflect.h2" +#line 404 "reflect.h2" class type_declaration; -#line 508 "reflect.h2" +#line 517 "reflect.h2" class alias_declaration; -#line 847 "reflect.h2" +#line 856 "reflect.h2" class value_member_info; -#line 1341 "reflect.h2" +#line 1350 "reflect.h2" } } @@ -325,7 +325,9 @@ class function_declaration public: [[nodiscard]] auto has_non_void_return_type() const& -> bool; public: [[nodiscard]] auto unnamed_return_type() const& -> std::string; + public: [[nodiscard]] auto get_parameters() const& -> std::vector; +#line 357 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -333,100 +335,100 @@ class function_declaration public: [[nodiscard]] auto make_virtual() & -> bool; public: function_declaration(function_declaration const& that); -#line 353 "reflect.h2" +#line 362 "reflect.h2" }; -#line 356 "reflect.h2" +#line 365 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 363 "reflect.h2" +#line 372 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 373 "reflect.h2" +#line 382 "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 383 "reflect.h2" +#line 392 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 389 "reflect.h2" +#line 398 "reflect.h2" }; -#line 392 "reflect.h2" +#line 401 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 399 "reflect.h2" +#line 408 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 409 "reflect.h2" +#line 418 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 421 "reflect.h2" +#line 430 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 435 "reflect.h2" +#line 444 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 445 "reflect.h2" +#line 454 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 455 "reflect.h2" +#line 464 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 465 "reflect.h2" +#line 474 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 475 "reflect.h2" +#line 484 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 490 "reflect.h2" +#line 499 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 498 "reflect.h2" +#line 507 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 502 "reflect.h2" +#line 511 "reflect.h2" }; -#line 505 "reflect.h2" +#line 514 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 512 "reflect.h2" +#line 521 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -435,10 +437,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 521 "reflect.h2" +#line 530 "reflect.h2" }; -#line 524 "reflect.h2" +#line 533 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -453,7 +455,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 542 "reflect.h2" +#line 551 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -468,7 +470,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 581 "reflect.h2" +#line 590 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -490,7 +492,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 625 "reflect.h2" +#line 634 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -516,7 +518,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 669 "reflect.h2" +#line 678 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -524,19 +526,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 679 "reflect.h2" +#line 688 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 687 "reflect.h2" +#line 696 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 696 "reflect.h2" +#line 705 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -555,7 +557,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 733 "reflect.h2" +#line 742 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -565,11 +567,11 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 758 "reflect.h2" +#line 767 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." -// +// // -- P0707R4, section 3 // // value - a value type that is totally ordered @@ -578,13 +580,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 774 "reflect.h2" +#line 783 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 780 "reflect.h2" +#line 789 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 787 "reflect.h2" +#line 796 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -612,7 +614,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 830 "reflect.h2" +#line 839 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -642,32 +644,32 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1022 "reflect.h2" +#line 1031 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a // value of its enumerators's type, and otherwise has only public // member variables of its enumerator's type, all of which are // naturally scoped because they are members of a type." -// +// // -- P0707R4, section 3 // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1048 "reflect.h2" +#line 1057 "reflect.h2" //----------------------------------------------------------------------- // -// "flag_enum expresses an enumeration that stores values +// "flag_enum expresses an enumeration that stores values // corresponding to bitwise-or'd enumerators. The enumerators must // be powers of two, and are automatically generated [...] A none // value is provided [...] Operators | and & are provided to // combine and extract values." -// +// // -- P0707R4, section 3 // auto flag_enum(meta::type_declaration& t) -> void; -#line 1080 "reflect.h2" +#line 1089 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -676,10 +678,10 @@ auto flag_enum(meta::type_declaration& t) -> void; // // -- Stroustrup (The Design and Evolution of C++, 14.3.4.1) // -// "C++17 needs a type-safe union... The implications of the -// consensus `variant` design are well understood and have been -// explored over several LEWG discussions, over a thousand emails, -// a joint LEWG/EWG session, and not to mention 12 years of +// "C++17 needs a type-safe union... The implications of the +// consensus `variant` design are well understood and have been +// explored over several LEWG discussions, over a thousand emails, +// a joint LEWG/EWG session, and not to mention 12 years of // experience with Boost and other libraries." // // -- Axel Naumann, in P0088 (wg21.link/p0088), @@ -688,20 +690,20 @@ auto flag_enum(meta::type_declaration& t) -> void; //----------------------------------------------------------------------- // // union -// +// // a type that contains exactly one of a fixed set of values at a time -// +// auto cpp2_union(meta::type_declaration& t) -> void; -#line 1227 "reflect.h2" +#line 1236 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1237 "reflect.h2" +#line 1246 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -712,7 +714,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1341 "reflect.h2" +#line 1350 "reflect.h2" } } @@ -1001,6 +1003,15 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::has_non_void_return_type() const& -> bool { return CPP2_UFCS(has_non_void_return_type)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto function_declaration::unnamed_return_type() const& -> std::string { return CPP2_UFCS(unnamed_return_type_to_string)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::get_parameters() const& -> std::vector + + { + std::vector ret {}; + for ( auto const& d : CPP2_UFCS(get_function_parameters)((*cpp2::assert_not_null(n))) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, &*cpp2::assert_not_null((*cpp2::assert_not_null(d)).declaration), (*this))); + } + return ret; + } [[nodiscard]] auto function_declaration::is_binary_comparison_function() const& -> bool { return CPP2_UFCS(is_binary_comparison_function)((*cpp2::assert_not_null(n))); } @@ -1011,14 +1022,14 @@ declaration::declaration(declaration const& that) function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 363 "reflect.h2" +#line 372 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 368 "reflect.h2" +#line 377 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1044,14 +1055,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 399 "reflect.h2" +#line 408 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 404 "reflect.h2" +#line 413 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1125,13 +1136,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 482 "reflect.h2" +#line 491 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 483 "reflect.h2" +#line 492 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1155,14 +1166,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 512 "reflect.h2" +#line 521 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 517 "reflect.h2" +#line 526 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1171,13 +1182,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 536 "reflect.h2" +#line 545 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 554 "reflect.h2" +#line 563 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1204,7 +1215,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 600 "reflect.h2" +#line 609 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1229,7 +1240,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 645 "reflect.h2" +#line 654 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1254,25 +1265,25 @@ auto ordered_impl( } } -#line 674 "reflect.h2" +#line 683 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 682 "reflect.h2" +#line 691 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 690 "reflect.h2" +#line 699 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 712 "reflect.h2" +#line 721 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1294,7 +1305,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 740 "reflect.h2" +#line 749 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1313,7 +1324,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 768 "reflect.h2" +#line 777 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1332,7 +1343,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 812 "reflect.h2" +#line 821 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1350,7 +1361,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 853 "reflect.h2" +#line 862 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1375,7 +1386,7 @@ auto basic_enum( { std::string value = "-1"; -#line 876 "reflect.h2" +#line 885 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1414,7 +1425,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 913 "reflect.h2" +#line 922 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1454,7 +1465,7 @@ std::string value = "-1"; } } -#line 953 "reflect.h2" +#line 962 "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' @@ -1493,7 +1504,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 989 "reflect.h2" +#line 998 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1525,10 +1536,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1019 "reflect.h2" +#line 1028 "reflect.h2" } -#line 1031 "reflect.h2" +#line 1040 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1545,7 +1556,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1058 "reflect.h2" +#line 1067 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1567,7 +1578,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1104 "reflect.h2" +#line 1113 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1576,7 +1587,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1111 "reflect.h2" +#line 1120 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1601,7 +1612,7 @@ auto value = 0; } while (false); ++value; } } -#line 1134 "reflect.h2" +#line 1143 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1616,7 +1627,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1149 "reflect.h2" +#line 1158 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1625,12 +1636,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1241 "reflect.h2" +#line 1250 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1820,7 +1831,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1341 "reflect.h2" +#line 1350 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index e9570825c4..999602170c 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -84,7 +84,7 @@ compiler_services: @polymorphic_base @copyable type = // First split this string into source_lines // - (copy newline_pos := source.find('\n')) + (copy newline_pos := source.find('\n')) if source.ssize() > 1 && newline_pos != source.npos { @@ -286,7 +286,7 @@ declaration: @polymorphic_base @copyable type = parent_is_polymorphic: (this) -> bool = n*.parent_is_polymorphic(); - mark_for_removal_from_enclosing_type: (inout this) + mark_for_removal_from_enclosing_type: (inout this) pre( parent_is_type() ) // this precondition should be sufficient ... = { test := n*.type_member_mark_for_removal(); @@ -344,6 +344,15 @@ function_declaration: @copyable type = has_non_void_return_type : (this) -> bool = n*.has_non_void_return_type(); unnamed_return_type : (this) -> std::string = n*.unnamed_return_type_to_string(); + get_parameters: (this) + -> std::vector + = { + ret: std::vector = (); + for n*.get_function_parameters() do (d) { + _ = ret.emplace_back( d*.declaration*&, this ); + } + return ret; + } is_binary_comparison_function: (this) -> bool = n*.is_binary_comparison_function(); @@ -406,7 +415,7 @@ type_declaration: @copyable type = assert( n*.is_type() ); } - reserve_names: (this, name: std::string_view, forward etc...) = + reserve_names: (this, name: std::string_view, forward etc...) = { // etc is not declared ':string_view' for compatibility with GCC 10.x for get_members() do (m) { @@ -758,7 +767,7 @@ basic_value: (inout t: meta::type_declaration) = //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." -// +// // -- P0707R4, section 3 // // value - a value type that is totally ordered @@ -910,7 +919,7 @@ basic_enum: ( } // Compute the default underlying type, if it wasn't explicitly specified - if underlying_type == "" + if underlying_type == "" { t.require( !found_non_numeric, "if you write an enumerator with a non-numeric-literal value, you must specify the enumeration's underlying type"); @@ -993,7 +1002,7 @@ basic_enum: ( to_string += " if this == none { return \"(none)\"; }\n"; } - for enumerators + for enumerators do (e) { if e.name != "_" { // ignore unnamed values if bitwise { @@ -1025,7 +1034,7 @@ basic_enum: ( // value of its enumerators's type, and otherwise has only public // member variables of its enumerator's type, all of which are // naturally scoped because they are members of a type." -// +// // -- P0707R4, section 3 // enum: (inout t: meta::type_declaration) = @@ -1047,12 +1056,12 @@ enum: (inout t: meta::type_declaration) = //----------------------------------------------------------------------- // -// "flag_enum expresses an enumeration that stores values +// "flag_enum expresses an enumeration that stores values // corresponding to bitwise-or'd enumerators. The enumerators must // be powers of two, and are automatically generated [...] A none // value is provided [...] Operators | and & are provided to // combine and extract values." -// +// // -- P0707R4, section 3 // flag_enum: (inout t: meta::type_declaration) = @@ -1085,10 +1094,10 @@ flag_enum: (inout t: meta::type_declaration) = // // -- Stroustrup (The Design and Evolution of C++, 14.3.4.1) // -// "C++17 needs a type-safe union... The implications of the -// consensus `variant` design are well understood and have been -// explored over several LEWG discussions, over a thousand emails, -// a joint LEWG/EWG session, and not to mention 12 years of +// "C++17 needs a type-safe union... The implications of the +// consensus `variant` design are well understood and have been +// explored over several LEWG discussions, over a thousand emails, +// a joint LEWG/EWG session, and not to mention 12 years of // experience with Boost and other libraries." // // -- Axel Naumann, in P0088 (wg21.link/p0088), @@ -1097,9 +1106,9 @@ flag_enum: (inout t: meta::type_declaration) = //----------------------------------------------------------------------- // // union -// +// // a type that contains exactly one of a fixed set of values at a time -// +// union: (inout t : meta::type_declaration) = { @@ -1154,8 +1163,8 @@ union: (inout t : meta::type_declaration) (copy storage: std::string = " _storage: std::aligned_storage_t bool = _discriminator == (a.value)$;\n"); @@ -1266,7 +1275,7 @@ apply_metafunctions: ( args: std::vector = (); for meta*.template_arguments() - do (arg) + do (arg) args.push_back( arg.to_string() ); rtype.set_metafunction_name( name, args ); @@ -1325,9 +1334,9 @@ apply_metafunctions: ( } if ( - !args.empty() + !args.empty() && !rtype.arguments_were_used() - ) + ) { error( name + " did not use its template arguments - did you mean to write '" + name + " <" + args[0] + "> type' (with the spaces)?"); return false; From c499d3b9230f299a62f72f6a553493da5bae9b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Tue, 14 Nov 2023 11:27:35 -0400 Subject: [PATCH 02/10] feat(reflect): add `function_declaration::add_initializer` --- source/reflect.h | 194 +++++++++++++++++++++++++--------------------- source/reflect.h2 | 12 +++ 2 files changed, 118 insertions(+), 88 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 0963ebcea3..ec8e3f89e4 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -27,19 +27,19 @@ class declaration; #line 301 "reflect.h2" class function_declaration; -#line 368 "reflect.h2" +#line 380 "reflect.h2" class object_declaration; -#line 404 "reflect.h2" +#line 416 "reflect.h2" class type_declaration; -#line 517 "reflect.h2" +#line 529 "reflect.h2" class alias_declaration; -#line 856 "reflect.h2" +#line 868 "reflect.h2" class value_member_info; -#line 1350 "reflect.h2" +#line 1362 "reflect.h2" } } @@ -333,102 +333,105 @@ class function_declaration public: auto default_to_virtual() & -> void; public: [[nodiscard]] auto make_virtual() & -> bool; + + public: auto add_initializer(cpp2::in source) && -> void; public: function_declaration(function_declaration const& that); -#line 362 "reflect.h2" + +#line 374 "reflect.h2" }; -#line 365 "reflect.h2" +#line 377 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 372 "reflect.h2" +#line 384 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 382 "reflect.h2" +#line 394 "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 392 "reflect.h2" +#line 404 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 398 "reflect.h2" +#line 410 "reflect.h2" }; -#line 401 "reflect.h2" +#line 413 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 408 "reflect.h2" +#line 420 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 418 "reflect.h2" +#line 430 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 430 "reflect.h2" +#line 442 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 444 "reflect.h2" +#line 456 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 454 "reflect.h2" +#line 466 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 464 "reflect.h2" +#line 476 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 474 "reflect.h2" +#line 486 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 484 "reflect.h2" +#line 496 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 499 "reflect.h2" +#line 511 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 507 "reflect.h2" +#line 519 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 511 "reflect.h2" +#line 523 "reflect.h2" }; -#line 514 "reflect.h2" +#line 526 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 521 "reflect.h2" +#line 533 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -437,10 +440,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 530 "reflect.h2" +#line 542 "reflect.h2" }; -#line 533 "reflect.h2" +#line 545 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -455,7 +458,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 551 "reflect.h2" +#line 563 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -470,7 +473,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 590 "reflect.h2" +#line 602 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -492,7 +495,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 634 "reflect.h2" +#line 646 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -518,7 +521,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 678 "reflect.h2" +#line 690 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -526,19 +529,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 688 "reflect.h2" +#line 700 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 696 "reflect.h2" +#line 708 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 705 "reflect.h2" +#line 717 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -557,7 +560,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 742 "reflect.h2" +#line 754 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -567,7 +570,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 767 "reflect.h2" +#line 779 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -580,13 +583,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 783 "reflect.h2" +#line 795 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 789 "reflect.h2" +#line 801 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 796 "reflect.h2" +#line 808 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -614,7 +617,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 839 "reflect.h2" +#line 851 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -644,7 +647,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1031 "reflect.h2" +#line 1043 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -656,7 +659,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1057 "reflect.h2" +#line 1069 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -669,7 +672,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1089 "reflect.h2" +#line 1101 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -696,14 +699,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1236 "reflect.h2" +#line 1248 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1246 "reflect.h2" +#line 1258 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -714,7 +717,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1350 "reflect.h2" +#line 1362 "reflect.h2" } } @@ -1019,17 +1022,32 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::make_virtual() & -> bool { return CPP2_UFCS(make_function_virtual)((*cpp2::assert_not_null(n))); } + auto function_declaration::add_initializer(cpp2::in source) && -> void + +#line 366 "reflect.h2" + { + cpp2::Default.expects(!(has_initializer()), ""); + cpp2::Default.expects(parent_is_type(), ""); +#line 367 "reflect.h2" + auto prefix {CPP2_UFCS(pretty_print_visualize)((*cpp2::assert_not_null(n)), 0)}; + CPP2_UFCS(back)(prefix) = ' ';// Remove final ';'. + auto p {CPP2_UFCS(as_type)(get_parent())}; + CPP2_UFCS(add_member)(p, std::move(prefix) + source); + static_cast(std::move(p)); + mark_for_removal_from_enclosing_type(); + } + function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 372 "reflect.h2" +#line 384 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 377 "reflect.h2" +#line 389 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1055,14 +1073,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 408 "reflect.h2" +#line 420 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 413 "reflect.h2" +#line 425 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1136,13 +1154,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 491 "reflect.h2" +#line 503 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 492 "reflect.h2" +#line 504 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1166,14 +1184,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 521 "reflect.h2" +#line 533 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 526 "reflect.h2" +#line 538 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1182,13 +1200,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 545 "reflect.h2" +#line 557 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 563 "reflect.h2" +#line 575 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1215,7 +1233,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 609 "reflect.h2" +#line 621 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1240,7 +1258,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 654 "reflect.h2" +#line 666 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1265,25 +1283,25 @@ auto ordered_impl( } } -#line 683 "reflect.h2" +#line 695 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 691 "reflect.h2" +#line 703 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 699 "reflect.h2" +#line 711 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 721 "reflect.h2" +#line 733 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1305,7 +1323,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 749 "reflect.h2" +#line 761 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1324,7 +1342,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 777 "reflect.h2" +#line 789 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1343,7 +1361,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 821 "reflect.h2" +#line 833 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1361,7 +1379,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 862 "reflect.h2" +#line 874 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1386,7 +1404,7 @@ auto basic_enum( { std::string value = "-1"; -#line 885 "reflect.h2" +#line 897 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1425,7 +1443,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 922 "reflect.h2" +#line 934 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1465,7 +1483,7 @@ std::string value = "-1"; } } -#line 962 "reflect.h2" +#line 974 "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' @@ -1504,7 +1522,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 998 "reflect.h2" +#line 1010 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1536,10 +1554,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1028 "reflect.h2" +#line 1040 "reflect.h2" } -#line 1040 "reflect.h2" +#line 1052 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1556,7 +1574,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1067 "reflect.h2" +#line 1079 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1578,7 +1596,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1113 "reflect.h2" +#line 1125 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1587,7 +1605,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1120 "reflect.h2" +#line 1132 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1612,7 +1630,7 @@ auto value = 0; } while (false); ++value; } } -#line 1143 "reflect.h2" +#line 1155 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1627,7 +1645,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1158 "reflect.h2" +#line 1170 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1636,12 +1654,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1250 "reflect.h2" +#line 1262 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1831,7 +1849,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1350 "reflect.h2" +#line 1362 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 999602170c..0613bfef8c 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -359,6 +359,18 @@ function_declaration: @copyable type = default_to_virtual : (inout this) = _ = n*.make_function_virtual(); make_virtual : (inout this) -> bool = n*.make_function_virtual(); + + add_initializer: (move this, source: std::string_view) + pre(!has_initializer()) + pre(parent_is_type()) + = { + prefix := n*.pretty_print_visualize(0); + prefix.back() = ' '; // Remove final ';'. + p := get_parent().as_type(); + p.add_member(prefix + source); + _ = p; + mark_for_removal_from_enclosing_type(); + } } From a51e2d1c71cfd734bfbdbf445d60d9aa28785a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Tue, 14 Nov 2023 12:28:49 -0400 Subject: [PATCH 03/10] fix(reflect): actually return the parent --- source/reflect.h | 2 +- source/reflect.h2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index ec8e3f89e4..3bc3ade148 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -934,7 +934,7 @@ declaration_base::declaration_base(declaration_base const& that) [[nodiscard]] auto declaration::as_type() const& -> type_declaration { return type_declaration(n, (*this)); } [[nodiscard]] auto declaration::as_alias() const& -> alias_declaration { return alias_declaration(n, (*this)); } - [[nodiscard]] auto declaration::get_parent() const& -> declaration { return declaration(n, (*this)); } + [[nodiscard]] auto declaration::get_parent() const& -> declaration { return declaration((*cpp2::assert_not_null(n)).parent_declaration, (*this)); } [[nodiscard]] auto declaration::parent_is_function() const& -> bool { return CPP2_UFCS(parent_is_function)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::parent_is_object() const& -> bool { return CPP2_UFCS(parent_is_object)((*cpp2::assert_not_null(n))); } diff --git a/source/reflect.h2 b/source/reflect.h2 index 0613bfef8c..ec2429848e 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -272,7 +272,7 @@ declaration: @polymorphic_base @copyable type = as_type : (this) -> type_declaration = type_declaration(n, this); as_alias : (this) -> alias_declaration = alias_declaration(n, this); - get_parent : (this) -> declaration = declaration(n, this); + get_parent : (this) -> declaration = declaration(n*.parent_declaration, this); parent_is_function : (this) -> bool = n*.parent_is_function(); parent_is_object : (this) -> bool = n*.parent_is_object(); From cb148bcf20082370d4271644fb22a2fa88148306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Fri, 17 Nov 2023 11:41:59 -0400 Subject: [PATCH 04/10] feat(reflect): add `declaration::get_arguments` --- source/reflect.h | 257 ++++++++++++++++++++++++---------------------- source/reflect.h2 | 7 ++ 2 files changed, 143 insertions(+), 121 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 3bc3ade148..3d48bffbe9 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -18,28 +18,28 @@ namespace meta { #line 32 "reflect.h2" class compiler_services; -#line 193 "reflect.h2" +#line 200 "reflect.h2" class declaration_base; -#line 219 "reflect.h2" +#line 226 "reflect.h2" class declaration; -#line 301 "reflect.h2" +#line 308 "reflect.h2" class function_declaration; -#line 380 "reflect.h2" +#line 387 "reflect.h2" class object_declaration; -#line 416 "reflect.h2" +#line 423 "reflect.h2" class type_declaration; -#line 529 "reflect.h2" +#line 536 "reflect.h2" class alias_declaration; -#line 868 "reflect.h2" +#line 875 "reflect.h2" class value_member_info; -#line 1362 "reflect.h2" +#line 1369 "reflect.h2" } } @@ -104,7 +104,10 @@ class compiler_services public: [[nodiscard]] auto get_argument(cpp2::in index) & -> std::string; -#line 70 "reflect.h2" +#line 69 "reflect.h2" + public: [[nodiscard]] auto get_arguments() & -> std::vector; + +#line 77 "reflect.h2" public: [[nodiscard]] auto arguments_were_used() const& -> bool; protected: [[nodiscard]] auto parse_statement( @@ -112,23 +115,23 @@ class compiler_services std::string_view source ) & -> std::unique_ptr; -#line 120 "reflect.h2" +#line 127 "reflect.h2" public: [[nodiscard]] virtual auto position() const -> source_position; -#line 126 "reflect.h2" +#line 133 "reflect.h2" public: auto require( cpp2::in b, cpp2::in msg ) const& -> void; -#line 137 "reflect.h2" +#line 144 "reflect.h2" public: auto error(cpp2::in msg) const& -> void; public: virtual ~compiler_services() noexcept; public: compiler_services(compiler_services const& that); -#line 145 "reflect.h2" +#line 152 "reflect.h2" }; /* @@ -167,7 +170,7 @@ type_id: @polymorphic_base @copyable type = } */ -#line 184 "reflect.h2" +#line 191 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -180,7 +183,7 @@ type_id: @polymorphic_base @copyable type = class declaration_base : public compiler_services { -#line 197 "reflect.h2" +#line 204 "reflect.h2" protected: declaration_node* n; protected: explicit declaration_base( @@ -189,31 +192,31 @@ class declaration_base cpp2::in s ); -#line 210 "reflect.h2" +#line 217 "reflect.h2" public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; public: virtual ~declaration_base() noexcept; public: declaration_base(declaration_base const& that); -#line 213 "reflect.h2" +#line 220 "reflect.h2" }; -#line 216 "reflect.h2" +#line 223 "reflect.h2" //----------------------------------------------------------------------- // All declarations // class declaration : public declaration_base { -#line 223 "reflect.h2" +#line 230 "reflect.h2" public: explicit declaration( declaration_node* n_, cpp2::in s ); -#line 232 "reflect.h2" +#line 239 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -232,7 +235,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 253 "reflect.h2" +#line 260 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto is_global() const& -> bool; @@ -275,24 +278,24 @@ public: declaration(declaration const& that); // this precondition should be sufficient ... -#line 295 "reflect.h2" +#line 302 "reflect.h2" }; -#line 298 "reflect.h2" +#line 305 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 305 "reflect.h2" +#line 312 "reflect.h2" public: explicit function_declaration( declaration_node* n_, cpp2::in s ); -#line 315 "reflect.h2" +#line 322 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const& -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const& -> bool; @@ -327,7 +330,7 @@ class function_declaration public: [[nodiscard]] auto unnamed_return_type() const& -> std::string; public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 357 "reflect.h2" +#line 364 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -338,100 +341,100 @@ class function_declaration public: function_declaration(function_declaration const& that); -#line 374 "reflect.h2" +#line 381 "reflect.h2" }; -#line 377 "reflect.h2" +#line 384 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 384 "reflect.h2" +#line 391 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 394 "reflect.h2" +#line 401 "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 404 "reflect.h2" +#line 411 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 410 "reflect.h2" +#line 417 "reflect.h2" }; -#line 413 "reflect.h2" +#line 420 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 420 "reflect.h2" +#line 427 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 430 "reflect.h2" +#line 437 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 442 "reflect.h2" +#line 449 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 456 "reflect.h2" +#line 463 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 466 "reflect.h2" +#line 473 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 476 "reflect.h2" +#line 483 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 486 "reflect.h2" +#line 493 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 496 "reflect.h2" +#line 503 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 511 "reflect.h2" +#line 518 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 519 "reflect.h2" +#line 526 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 523 "reflect.h2" +#line 530 "reflect.h2" }; -#line 526 "reflect.h2" +#line 533 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 533 "reflect.h2" +#line 540 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -440,10 +443,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 542 "reflect.h2" +#line 549 "reflect.h2" }; -#line 545 "reflect.h2" +#line 552 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -458,7 +461,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 563 "reflect.h2" +#line 570 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -473,7 +476,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 602 "reflect.h2" +#line 609 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -495,7 +498,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 646 "reflect.h2" +#line 653 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -521,7 +524,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 690 "reflect.h2" +#line 697 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -529,19 +532,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 700 "reflect.h2" +#line 707 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 708 "reflect.h2" +#line 715 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 717 "reflect.h2" +#line 724 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -560,7 +563,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 754 "reflect.h2" +#line 761 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -570,7 +573,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 779 "reflect.h2" +#line 786 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -583,13 +586,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 795 "reflect.h2" +#line 802 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 801 "reflect.h2" +#line 808 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 808 "reflect.h2" +#line 815 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -617,7 +620,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 851 "reflect.h2" +#line 858 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -647,7 +650,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1043 "reflect.h2" +#line 1050 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -659,7 +662,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1069 "reflect.h2" +#line 1076 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -672,7 +675,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1101 "reflect.h2" +#line 1108 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -699,14 +702,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1248 "reflect.h2" +#line 1255 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1258 "reflect.h2" +#line 1265 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -717,7 +720,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1362 "reflect.h2" +#line 1369 "reflect.h2" } } @@ -763,6 +766,18 @@ namespace meta { } return ""; } + [[nodiscard]] auto compiler_services::get_arguments() & -> std::vector{ + std::vector ret {}; +{ +auto count = 0; + +#line 72 "reflect.h2" + while( !(CPP2_UFCS(empty)(CPP2_UFCS(emplace_back)(ret, get_argument(count)))) ) {++count; } +}// No `next` (#832). +#line 73 "reflect.h2" + CPP2_UFCS(pop_back)(ret); + return ret; + } [[nodiscard]] auto compiler_services::arguments_were_used() const& -> bool { return metafunctions_used; } @@ -784,7 +799,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // -#line 88 "reflect.h2" +#line 95 "reflect.h2" if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos != source.npos) { @@ -797,7 +812,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); } } -#line 99 "reflect.h2" +#line 106 "reflect.h2" if (!(CPP2_UFCS(empty)(source))) { std::move(add_line)(std::move(source)); } @@ -855,7 +870,7 @@ compiler_services::compiler_services(compiler_services const& that) , metafunction_args{ that.metafunction_args } , metafunctions_used{ that.metafunctions_used }{} -#line 199 "reflect.h2" +#line 206 "reflect.h2" declaration_base::declaration_base( declaration_node* n_, @@ -863,10 +878,10 @@ compiler_services::compiler_services(compiler_services const& that) ) : compiler_services{ s } , n{ n_ } -#line 204 "reflect.h2" +#line 211 "reflect.h2" { -#line 207 "reflect.h2" +#line 214 "reflect.h2" cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } @@ -879,14 +894,14 @@ declaration_base::declaration_base(declaration_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} -#line 223 "reflect.h2" +#line 230 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::in s ) : declaration_base{ n_, s } -#line 228 "reflect.h2" +#line 235 "reflect.h2" { } @@ -952,7 +967,7 @@ declaration_base::declaration_base(declaration_base const& that) { cpp2::Type.expects(parent_is_type(), ""); -#line 292 "reflect.h2" +#line 299 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -961,14 +976,14 @@ declaration_base::declaration_base(declaration_base const& that) declaration::declaration(declaration const& that) : declaration_base{ static_cast(that) }{} -#line 305 "reflect.h2" +#line 312 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 310 "reflect.h2" +#line 317 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); @@ -1024,11 +1039,11 @@ declaration::declaration(declaration const& that) auto function_declaration::add_initializer(cpp2::in source) && -> void -#line 366 "reflect.h2" +#line 373 "reflect.h2" { cpp2::Default.expects(!(has_initializer()), ""); cpp2::Default.expects(parent_is_type(), ""); -#line 367 "reflect.h2" +#line 374 "reflect.h2" auto prefix {CPP2_UFCS(pretty_print_visualize)((*cpp2::assert_not_null(n)), 0)}; CPP2_UFCS(back)(prefix) = ' ';// Remove final ';'. auto p {CPP2_UFCS(as_type)(get_parent())}; @@ -1040,14 +1055,14 @@ declaration::declaration(declaration const& that) function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 384 "reflect.h2" +#line 391 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 389 "reflect.h2" +#line 396 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1073,14 +1088,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 420 "reflect.h2" +#line 427 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 425 "reflect.h2" +#line 432 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1154,13 +1169,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 503 "reflect.h2" +#line 510 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 504 "reflect.h2" +#line 511 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1184,14 +1199,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 533 "reflect.h2" +#line 540 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 538 "reflect.h2" +#line 545 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1200,13 +1215,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 557 "reflect.h2" +#line 564 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 575 "reflect.h2" +#line 582 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1233,7 +1248,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 621 "reflect.h2" +#line 628 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1258,7 +1273,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 666 "reflect.h2" +#line 673 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1283,25 +1298,25 @@ auto ordered_impl( } } -#line 695 "reflect.h2" +#line 702 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 703 "reflect.h2" +#line 710 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 711 "reflect.h2" +#line 718 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 733 "reflect.h2" +#line 740 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1323,7 +1338,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 761 "reflect.h2" +#line 768 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1342,7 +1357,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 789 "reflect.h2" +#line 796 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1361,7 +1376,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 833 "reflect.h2" +#line 840 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1379,7 +1394,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 874 "reflect.h2" +#line 881 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1404,7 +1419,7 @@ auto basic_enum( { std::string value = "-1"; -#line 897 "reflect.h2" +#line 904 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1443,7 +1458,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 934 "reflect.h2" +#line 941 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1483,7 +1498,7 @@ std::string value = "-1"; } } -#line 974 "reflect.h2" +#line 981 "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' @@ -1522,7 +1537,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1010 "reflect.h2" +#line 1017 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1554,10 +1569,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1040 "reflect.h2" +#line 1047 "reflect.h2" } -#line 1052 "reflect.h2" +#line 1059 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1574,7 +1589,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1079 "reflect.h2" +#line 1086 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1596,7 +1611,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1125 "reflect.h2" +#line 1132 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1605,7 +1620,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1132 "reflect.h2" +#line 1139 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1630,7 +1645,7 @@ auto value = 0; } while (false); ++value; } } -#line 1155 "reflect.h2" +#line 1162 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1645,7 +1660,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1170 "reflect.h2" +#line 1177 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1654,12 +1669,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1262 "reflect.h2" +#line 1269 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1849,7 +1864,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1362 "reflect.h2" +#line 1369 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index ec2429848e..0c6c598262 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -66,6 +66,13 @@ compiler_services: @polymorphic_base @copyable type = } return ""; } + get_arguments: (inout this) -> std::vector = { + ret: std::vector = (); + (copy count := 0) + while !ret.emplace_back(get_argument(count)).empty() { count++; } // No `next` (#832). + ret.pop_back(); + return ret; + } arguments_were_used: (this) -> bool = metafunctions_used; From 66e83d2b0c16bf5c98caf6dd283689c272394776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Fri, 17 Nov 2023 12:00:56 -0400 Subject: [PATCH 05/10] feat(reflect): add `get_member_functions_needing_initializer` --- source/reflect.h | 160 ++++++++++++++++++++++++++-------------------- source/reflect.h2 | 15 +++++ 2 files changed, 104 insertions(+), 71 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 3d48bffbe9..57c4942b0f 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -33,13 +33,13 @@ class object_declaration; #line 423 "reflect.h2" class type_declaration; -#line 536 "reflect.h2" +#line 551 "reflect.h2" class alias_declaration; -#line 875 "reflect.h2" +#line 890 "reflect.h2" class value_member_info; -#line 1369 "reflect.h2" +#line 1384 "reflect.h2" } } @@ -397,44 +397,47 @@ class type_declaration public: [[nodiscard]] auto get_member_functions() const& -> std::vector; #line 463 "reflect.h2" + public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; + +#line 478 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 473 "reflect.h2" +#line 488 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 483 "reflect.h2" +#line 498 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 493 "reflect.h2" +#line 508 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 503 "reflect.h2" +#line 518 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 518 "reflect.h2" +#line 533 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 526 "reflect.h2" +#line 541 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 530 "reflect.h2" +#line 545 "reflect.h2" }; -#line 533 "reflect.h2" +#line 548 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 540 "reflect.h2" +#line 555 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -443,10 +446,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 549 "reflect.h2" +#line 564 "reflect.h2" }; -#line 552 "reflect.h2" +#line 567 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -461,7 +464,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 570 "reflect.h2" +#line 585 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -476,7 +479,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 609 "reflect.h2" +#line 624 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -498,7 +501,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 653 "reflect.h2" +#line 668 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -524,7 +527,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 697 "reflect.h2" +#line 712 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -532,19 +535,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 707 "reflect.h2" +#line 722 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 715 "reflect.h2" +#line 730 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 724 "reflect.h2" +#line 739 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -563,7 +566,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 761 "reflect.h2" +#line 776 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -573,7 +576,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 786 "reflect.h2" +#line 801 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -586,13 +589,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 802 "reflect.h2" +#line 817 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 808 "reflect.h2" +#line 823 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 815 "reflect.h2" +#line 830 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -620,7 +623,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 858 "reflect.h2" +#line 873 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -650,7 +653,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1050 "reflect.h2" +#line 1065 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -662,7 +665,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1076 "reflect.h2" +#line 1091 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -675,7 +678,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1108 "reflect.h2" +#line 1123 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -702,14 +705,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1255 "reflect.h2" +#line 1270 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1265 "reflect.h2" +#line 1280 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -720,7 +723,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1369 "reflect.h2" +#line 1384 "reflect.h2" } } @@ -1127,6 +1130,21 @@ declaration::declaration(declaration const& that) return ret; } + [[nodiscard]] auto type_declaration::get_member_functions_needing_initializer() const& -> std::vector + + { + std::vector ret {}; + for ( + auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) + if (!(CPP2_UFCS(has_initializer)((*cpp2::assert_not_null(d)))) + && !(CPP2_UFCS(is_virtual_function)((*cpp2::assert_not_null(d)))) + && !(CPP2_UFCS(is_defaultable_function)((*cpp2::assert_not_null(d))))) + { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); + } + return ret; + } + [[nodiscard]] auto type_declaration::get_member_objects() const& -> std::vector { @@ -1169,13 +1187,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 510 "reflect.h2" +#line 525 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 511 "reflect.h2" +#line 526 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1199,14 +1217,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 540 "reflect.h2" +#line 555 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 545 "reflect.h2" +#line 560 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1215,13 +1233,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 564 "reflect.h2" +#line 579 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 582 "reflect.h2" +#line 597 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1248,7 +1266,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 628 "reflect.h2" +#line 643 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1273,7 +1291,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 673 "reflect.h2" +#line 688 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1298,25 +1316,25 @@ auto ordered_impl( } } -#line 702 "reflect.h2" +#line 717 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 710 "reflect.h2" +#line 725 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 718 "reflect.h2" +#line 733 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 740 "reflect.h2" +#line 755 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1338,7 +1356,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 768 "reflect.h2" +#line 783 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1357,7 +1375,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 796 "reflect.h2" +#line 811 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1376,7 +1394,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 840 "reflect.h2" +#line 855 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1394,7 +1412,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 881 "reflect.h2" +#line 896 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1419,7 +1437,7 @@ auto basic_enum( { std::string value = "-1"; -#line 904 "reflect.h2" +#line 919 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1458,7 +1476,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 941 "reflect.h2" +#line 956 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1498,7 +1516,7 @@ std::string value = "-1"; } } -#line 981 "reflect.h2" +#line 996 "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' @@ -1537,7 +1555,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1017 "reflect.h2" +#line 1032 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1569,10 +1587,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1047 "reflect.h2" +#line 1062 "reflect.h2" } -#line 1059 "reflect.h2" +#line 1074 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1589,7 +1607,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1086 "reflect.h2" +#line 1101 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1611,7 +1629,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1132 "reflect.h2" +#line 1147 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1620,7 +1638,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1139 "reflect.h2" +#line 1154 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1645,7 +1663,7 @@ auto value = 0; } while (false); ++value; } } -#line 1162 "reflect.h2" +#line 1177 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1660,7 +1678,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1177 "reflect.h2" +#line 1192 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1669,12 +1687,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1269 "reflect.h2" +#line 1284 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1864,7 +1882,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1369 "reflect.h2" +#line 1384 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 0c6c598262..29aa057f5e 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -460,6 +460,21 @@ type_declaration: @copyable type = return ret; } + get_member_functions_needing_initializer: (this) + -> std::vector + = { + ret: std::vector = (); + for n*.get_type_scope_declarations(declaration_node::functions) + do (d) + if !d*.has_initializer() + && !d*.is_virtual_function() + && !d*.is_defaultable_function() + { + _ = ret.emplace_back( d, this ); + } + return ret; + } + get_member_objects: (this) -> std::vector = { From 8676473f58af19e38e14329a68e51637ad6cb090 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Fri, 15 Dec 2023 13:56:16 -1000 Subject: [PATCH 06/10] Pre-merge review pass Johel, can you give this a try in your test code and make sure your test code still works as expected? I had to create a little test to exercise it, since the new functions aren't used in this PR. --- source/parse.h | 54 +++++--- source/reflect.h | 306 +++++++++++++++++++++++----------------------- source/reflect.h2 | 53 ++++---- 3 files changed, 221 insertions(+), 192 deletions(-) diff --git a/source/parse.h b/source/parse.h index 39893e6f2e..ef49b05081 100644 --- a/source/parse.h +++ b/source/parse.h @@ -2982,7 +2982,7 @@ struct declaration_node } - auto add_type_member( std::unique_ptr statement ) + auto add_type_member( std::unique_ptr&& statement ) -> bool { if ( @@ -3014,6 +3014,23 @@ struct declaration_node } + auto add_function_initializer( std::unique_ptr&& statement ) + -> bool + { + if ( + !is_function() + || initializer + ) + { + return false; + } + + // Adopt it as our initializer statement + initializer = std::move( statement ); + return true; + } + + auto get_decl_if_type_scope_object_name_before_a_base_type( std::string_view s ) const -> declaration_node const* { @@ -3384,13 +3401,17 @@ struct declaration_node } auto get_function_parameters() - -> std::span> + -> std::vector { if (!is_function()) { return {}; } // else - return std::get(type)->parameters->parameters; + auto ret = std::vector{}; + for (auto& param : std::get(type)->parameters->parameters) { + ret.push_back( param.get() ); + } + return ret; } auto unnamed_return_type_to_string() const @@ -5261,17 +5282,22 @@ class parser tokens = &tokens_; generated_tokens = &generated_tokens_; - // Parse one declaration - we succeed if the parse succeeded, - // and there were no new errors, and all tokens were consumed - auto errors_size = std::ssize(errors); - pos = 0; - if (auto d = statement(); - d - && std::ssize(errors) == errors_size - && done() - ) - { - return d; + try { + // Parse one declaration - we succeed if the parse succeeded, + // and there were no new errors, and all tokens were consumed + auto errors_size = std::ssize(errors); + pos = 0; + if (auto d = statement(); + d + && std::ssize(errors) == errors_size + && done() + ) + { + return d; + } + } + catch(std::runtime_error& e) { + error(e.what(), true, {}, true); } return {}; diff --git a/source/reflect.h b/source/reflect.h index 57c4942b0f..a28d0e2ef9 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -18,28 +18,28 @@ namespace meta { #line 32 "reflect.h2" class compiler_services; -#line 200 "reflect.h2" +#line 198 "reflect.h2" class declaration_base; -#line 226 "reflect.h2" +#line 224 "reflect.h2" class declaration; -#line 308 "reflect.h2" +#line 306 "reflect.h2" class function_declaration; -#line 387 "reflect.h2" +#line 388 "reflect.h2" class object_declaration; -#line 423 "reflect.h2" +#line 424 "reflect.h2" class type_declaration; -#line 551 "reflect.h2" +#line 556 "reflect.h2" class alias_declaration; -#line 890 "reflect.h2" +#line 895 "reflect.h2" class value_member_info; -#line 1384 "reflect.h2" +#line 1389 "reflect.h2" } } @@ -104,10 +104,10 @@ class compiler_services public: [[nodiscard]] auto get_argument(cpp2::in index) & -> std::string; -#line 69 "reflect.h2" +#line 70 "reflect.h2" public: [[nodiscard]] auto get_arguments() & -> std::vector; -#line 77 "reflect.h2" +#line 75 "reflect.h2" public: [[nodiscard]] auto arguments_were_used() const& -> bool; protected: [[nodiscard]] auto parse_statement( @@ -115,23 +115,23 @@ class compiler_services std::string_view source ) & -> std::unique_ptr; -#line 127 "reflect.h2" +#line 125 "reflect.h2" public: [[nodiscard]] virtual auto position() const -> source_position; -#line 133 "reflect.h2" +#line 131 "reflect.h2" public: auto require( cpp2::in b, cpp2::in msg ) const& -> void; -#line 144 "reflect.h2" +#line 142 "reflect.h2" public: auto error(cpp2::in msg) const& -> void; public: virtual ~compiler_services() noexcept; public: compiler_services(compiler_services const& that); -#line 152 "reflect.h2" +#line 150 "reflect.h2" }; /* @@ -170,7 +170,7 @@ type_id: @polymorphic_base @copyable type = } */ -#line 191 "reflect.h2" +#line 189 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -183,7 +183,7 @@ type_id: @polymorphic_base @copyable type = class declaration_base : public compiler_services { -#line 204 "reflect.h2" +#line 202 "reflect.h2" protected: declaration_node* n; protected: explicit declaration_base( @@ -192,31 +192,31 @@ class declaration_base cpp2::in s ); -#line 217 "reflect.h2" +#line 215 "reflect.h2" public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; public: virtual ~declaration_base() noexcept; public: declaration_base(declaration_base const& that); -#line 220 "reflect.h2" +#line 218 "reflect.h2" }; -#line 223 "reflect.h2" +#line 221 "reflect.h2" //----------------------------------------------------------------------- // All declarations // class declaration : public declaration_base { -#line 230 "reflect.h2" +#line 228 "reflect.h2" public: explicit declaration( declaration_node* n_, cpp2::in s ); -#line 239 "reflect.h2" +#line 237 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -235,7 +235,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 260 "reflect.h2" +#line 258 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto is_global() const& -> bool; @@ -278,24 +278,24 @@ public: declaration(declaration const& that); // this precondition should be sufficient ... -#line 302 "reflect.h2" +#line 300 "reflect.h2" }; -#line 305 "reflect.h2" +#line 303 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 312 "reflect.h2" +#line 310 "reflect.h2" public: explicit function_declaration( declaration_node* n_, cpp2::in s ); -#line 322 "reflect.h2" +#line 320 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const& -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const& -> bool; @@ -328,116 +328,117 @@ class function_declaration public: [[nodiscard]] auto has_non_void_return_type() const& -> bool; public: [[nodiscard]] auto unnamed_return_type() const& -> std::string; + public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 364 "reflect.h2" +#line 363 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; public: [[nodiscard]] auto make_virtual() & -> bool; - public: auto add_initializer(cpp2::in source) && -> void; + public: auto add_initializer(cpp2::in source) & -> void; public: function_declaration(function_declaration const& that); -#line 381 "reflect.h2" +#line 382 "reflect.h2" }; -#line 384 "reflect.h2" +#line 385 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 391 "reflect.h2" +#line 392 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 401 "reflect.h2" +#line 402 "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 411 "reflect.h2" +#line 412 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 417 "reflect.h2" +#line 418 "reflect.h2" }; -#line 420 "reflect.h2" +#line 421 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 427 "reflect.h2" +#line 428 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 437 "reflect.h2" +#line 438 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 449 "reflect.h2" +#line 450 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 463 "reflect.h2" +#line 465 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 478 "reflect.h2" +#line 480 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 488 "reflect.h2" +#line 490 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 498 "reflect.h2" +#line 500 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 508 "reflect.h2" +#line 510 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 518 "reflect.h2" +#line 520 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 533 "reflect.h2" +#line 535 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 541 "reflect.h2" +#line 546 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 545 "reflect.h2" +#line 550 "reflect.h2" }; -#line 548 "reflect.h2" +#line 553 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 555 "reflect.h2" +#line 560 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -446,10 +447,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 564 "reflect.h2" +#line 569 "reflect.h2" }; -#line 567 "reflect.h2" +#line 572 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -464,7 +465,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 585 "reflect.h2" +#line 590 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -479,7 +480,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 624 "reflect.h2" +#line 629 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -501,7 +502,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 668 "reflect.h2" +#line 673 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -527,7 +528,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 712 "reflect.h2" +#line 717 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -535,19 +536,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 722 "reflect.h2" +#line 727 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 730 "reflect.h2" +#line 735 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 739 "reflect.h2" +#line 744 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -566,7 +567,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 776 "reflect.h2" +#line 781 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -576,7 +577,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 801 "reflect.h2" +#line 806 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -589,13 +590,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 817 "reflect.h2" +#line 822 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 823 "reflect.h2" +#line 828 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 830 "reflect.h2" +#line 835 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -623,7 +624,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 873 "reflect.h2" +#line 878 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -653,7 +654,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1065 "reflect.h2" +#line 1070 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -665,7 +666,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1091 "reflect.h2" +#line 1096 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -678,7 +679,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1123 "reflect.h2" +#line 1128 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -705,14 +706,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1270 "reflect.h2" +#line 1275 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1280 "reflect.h2" +#line 1285 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -723,7 +724,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1384 "reflect.h2" +#line 1389 "reflect.h2" } } @@ -769,17 +770,10 @@ namespace meta { } return ""; } - [[nodiscard]] auto compiler_services::get_arguments() & -> std::vector{ - std::vector ret {}; -{ -auto count = 0; -#line 72 "reflect.h2" - while( !(CPP2_UFCS(empty)(CPP2_UFCS(emplace_back)(ret, get_argument(count)))) ) {++count; } -}// No `next` (#832). -#line 73 "reflect.h2" - CPP2_UFCS(pop_back)(ret); - return ret; + [[nodiscard]] auto compiler_services::get_arguments() & -> std::vector{ + metafunctions_used = true; + return metafunction_args; } [[nodiscard]] auto compiler_services::arguments_were_used() const& -> bool { return metafunctions_used; } @@ -802,7 +796,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // -#line 95 "reflect.h2" +#line 93 "reflect.h2" if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos != source.npos) { @@ -815,7 +809,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); } } -#line 106 "reflect.h2" +#line 104 "reflect.h2" if (!(CPP2_UFCS(empty)(source))) { std::move(add_line)(std::move(source)); } @@ -873,7 +867,7 @@ compiler_services::compiler_services(compiler_services const& that) , metafunction_args{ that.metafunction_args } , metafunctions_used{ that.metafunctions_used }{} -#line 206 "reflect.h2" +#line 204 "reflect.h2" declaration_base::declaration_base( declaration_node* n_, @@ -881,10 +875,10 @@ compiler_services::compiler_services(compiler_services const& that) ) : compiler_services{ s } , n{ n_ } -#line 211 "reflect.h2" +#line 209 "reflect.h2" { -#line 214 "reflect.h2" +#line 212 "reflect.h2" cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } @@ -897,14 +891,14 @@ declaration_base::declaration_base(declaration_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} -#line 230 "reflect.h2" +#line 228 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::in s ) : declaration_base{ n_, s } -#line 235 "reflect.h2" +#line 233 "reflect.h2" { } @@ -970,7 +964,7 @@ declaration_base::declaration_base(declaration_base const& that) { cpp2::Type.expects(parent_is_type(), ""); -#line 299 "reflect.h2" +#line 297 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -979,14 +973,14 @@ declaration_base::declaration_base(declaration_base const& that) declaration::declaration(declaration const& that) : declaration_base{ static_cast(that) }{} -#line 312 "reflect.h2" +#line 310 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 317 "reflect.h2" +#line 315 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); @@ -1024,12 +1018,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::has_non_void_return_type() const& -> bool { return CPP2_UFCS(has_non_void_return_type)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto function_declaration::unnamed_return_type() const& -> std::string { return CPP2_UFCS(unnamed_return_type_to_string)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::get_parameters() const& -> std::vector { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_function_parameters)((*cpp2::assert_not_null(n))) ) { - static_cast(CPP2_UFCS(emplace_back)(ret, &*cpp2::assert_not_null((*cpp2::assert_not_null(d)).declaration), (*this))); + for ( auto const& param : CPP2_UFCS(get_function_parameters)((*cpp2::assert_not_null(n))) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, &*cpp2::assert_not_null((*cpp2::assert_not_null(param)).declaration), (*this))); } return ret; } @@ -1040,32 +1035,31 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::make_virtual() & -> bool { return CPP2_UFCS(make_function_virtual)((*cpp2::assert_not_null(n))); } - auto function_declaration::add_initializer(cpp2::in source) && -> void - -#line 373 "reflect.h2" + auto function_declaration::add_initializer(cpp2::in source) & -> void { - cpp2::Default.expects(!(has_initializer()), ""); - cpp2::Default.expects(parent_is_type(), ""); -#line 374 "reflect.h2" - auto prefix {CPP2_UFCS(pretty_print_visualize)((*cpp2::assert_not_null(n)), 0)}; - CPP2_UFCS(back)(prefix) = ' ';// Remove final ';'. - auto p {CPP2_UFCS(as_type)(get_parent())}; - CPP2_UFCS(add_member)(p, std::move(prefix) + source); - static_cast(std::move(p)); - mark_for_removal_from_enclosing_type(); + require(!(has_initializer()), + "cannot add an initializer to a function that already has one"); + require(parent_is_type(), + "cannot add an initializer to a function that isn't in a type scope"); + + auto stmt {parse_statement(source)}; + require(cpp2::as_(stmt), + std::string("cannot add an initializer that is not a valid statement: ") + source); + require(CPP2_UFCS(add_function_initializer)((*cpp2::assert_not_null(n)), std::move(stmt)), + std::string("error attempting to add initializer:\n") + source); } function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 391 "reflect.h2" +#line 392 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 396 "reflect.h2" +#line 397 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1091,14 +1085,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 427 "reflect.h2" +#line 428 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 432 "reflect.h2" +#line 433 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1124,7 +1118,8 @@ declaration::declaration(declaration const& that) { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) { + for ( + auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) { static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; @@ -1135,10 +1130,10 @@ declaration::declaration(declaration const& that) { std::vector ret {}; for ( - auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) - if (!(CPP2_UFCS(has_initializer)((*cpp2::assert_not_null(d)))) - && !(CPP2_UFCS(is_virtual_function)((*cpp2::assert_not_null(d)))) - && !(CPP2_UFCS(is_defaultable_function)((*cpp2::assert_not_null(d))))) + auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) + if ( !(CPP2_UFCS(has_initializer)((*cpp2::assert_not_null(d)))) + && !(CPP2_UFCS(is_virtual_function)((*cpp2::assert_not_null(d)))) + && !(CPP2_UFCS(is_defaultable_function)((*cpp2::assert_not_null(d))))) { static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } @@ -1187,13 +1182,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 525 "reflect.h2" +#line 527 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 526 "reflect.h2" +#line 528 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1204,9 +1199,12 @@ declaration::declaration(declaration const& that) auto type_declaration::add_member(cpp2::in source) & -> void { auto decl {parse_statement(source)}; - if (!(decl) || !(CPP2_UFCS(add_type_member)((*cpp2::assert_not_null(n)), std::move(decl)))) { - error(std::string("error attempting to add member:\n") + source); - } + require(cpp2::as_(decl), + "the provided source string is not a valid statement"); + require(CPP2_UFCS(is_declaration)((*cpp2::assert_not_null(decl))), + "cannot add a member that is not a declaration"); + require(CPP2_UFCS(add_type_member)((*cpp2::assert_not_null(n)), std::move(decl)), + std::string("error attempting to add member:\n") + source); } auto type_declaration::remove_marked_members() & -> void { CPP2_UFCS(type_remove_marked_members)((*cpp2::assert_not_null(n))); } @@ -1217,14 +1215,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 555 "reflect.h2" +#line 560 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 560 "reflect.h2" +#line 565 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1233,13 +1231,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 579 "reflect.h2" +#line 584 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 597 "reflect.h2" +#line 602 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1266,7 +1264,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 643 "reflect.h2" +#line 648 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1291,7 +1289,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 688 "reflect.h2" +#line 693 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1316,25 +1314,25 @@ auto ordered_impl( } } -#line 717 "reflect.h2" +#line 722 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 725 "reflect.h2" +#line 730 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 733 "reflect.h2" +#line 738 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 755 "reflect.h2" +#line 760 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1356,7 +1354,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 783 "reflect.h2" +#line 788 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1375,7 +1373,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 811 "reflect.h2" +#line 816 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1394,7 +1392,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 855 "reflect.h2" +#line 860 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1412,7 +1410,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 896 "reflect.h2" +#line 901 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1437,7 +1435,7 @@ auto basic_enum( { std::string value = "-1"; -#line 919 "reflect.h2" +#line 924 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1476,7 +1474,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 956 "reflect.h2" +#line 961 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1516,7 +1514,7 @@ std::string value = "-1"; } } -#line 996 "reflect.h2" +#line 1001 "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' @@ -1555,7 +1553,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1032 "reflect.h2" +#line 1037 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1587,10 +1585,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1062 "reflect.h2" +#line 1067 "reflect.h2" } -#line 1074 "reflect.h2" +#line 1079 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1607,7 +1605,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1101 "reflect.h2" +#line 1106 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1629,7 +1627,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1147 "reflect.h2" +#line 1152 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1638,7 +1636,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1154 "reflect.h2" +#line 1159 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1663,7 +1661,7 @@ auto value = 0; } while (false); ++value; } } -#line 1177 "reflect.h2" +#line 1182 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1678,7 +1676,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1192 "reflect.h2" +#line 1197 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1687,12 +1685,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1284 "reflect.h2" +#line 1289 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1882,7 +1880,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1384 "reflect.h2" +#line 1389 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 29aa057f5e..258f82316f 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -66,12 +66,10 @@ compiler_services: @polymorphic_base @copyable type = } return ""; } + get_arguments: (inout this) -> std::vector = { - ret: std::vector = (); - (copy count := 0) - while !ret.emplace_back(get_argument(count)).empty() { count++; } // No `next` (#832). - ret.pop_back(); - return ret; + metafunctions_used = true; + return metafunction_args; } arguments_were_used: (this) -> bool = metafunctions_used; @@ -351,12 +349,13 @@ function_declaration: @copyable type = has_non_void_return_type : (this) -> bool = n*.has_non_void_return_type(); unnamed_return_type : (this) -> std::string = n*.unnamed_return_type_to_string(); + get_parameters: (this) -> std::vector = { ret: std::vector = (); - for n*.get_function_parameters() do (d) { - _ = ret.emplace_back( d*.declaration*&, this ); + for n*.get_function_parameters() do (param) { + _ = ret.emplace_back( param*.declaration*&, this ); } return ret; } @@ -367,16 +366,18 @@ function_declaration: @copyable type = make_virtual : (inout this) -> bool = n*.make_function_virtual(); - add_initializer: (move this, source: std::string_view) - pre(!has_initializer()) - pre(parent_is_type()) + add_initializer: (inout this, source: std::string_view) = { - prefix := n*.pretty_print_visualize(0); - prefix.back() = ' '; // Remove final ';'. - p := get_parent().as_type(); - p.add_member(prefix + source); - _ = p; - mark_for_removal_from_enclosing_type(); + require( !has_initializer(), + "cannot add an initializer to a function that already has one"); + require( parent_is_type(), + "cannot add an initializer to a function that isn't in a type scope"); + + stmt := parse_statement(source); + require( stmt as bool, + std::string("cannot add an initializer that is not a valid statement: ") + source); + require (n*.add_function_initializer(stmt), + std::string("error attempting to add initializer:\n") + source); } } @@ -454,7 +455,8 @@ type_declaration: @copyable type = -> std::vector = { ret: std::vector = (); - for n*.get_type_scope_declarations(declaration_node::functions) do (d) { + for n*.get_type_scope_declarations(declaration_node::functions) + do (d) { _ = ret.emplace_back( d, this ); } return ret; @@ -465,10 +467,10 @@ type_declaration: @copyable type = = { ret: std::vector = (); for n*.get_type_scope_declarations(declaration_node::functions) - do (d) - if !d*.has_initializer() - && !d*.is_virtual_function() - && !d*.is_defaultable_function() + do (d) + if !d*.has_initializer() + && !d*.is_virtual_function() + && !d*.is_defaultable_function() { _ = ret.emplace_back( d, this ); } @@ -533,9 +535,12 @@ type_declaration: @copyable type = add_member: (inout this, source: std::string_view) = { decl := parse_statement(source); - if !decl || !n*.add_type_member(decl) { - error( std::string("error attempting to add member:\n") + source ); - } + require( decl as bool, + "the provided source string is not a valid statement"); + require( decl*.is_declaration(), + "cannot add a member that is not a declaration"); + require( n*.add_type_member(decl), + std::string("error attempting to add member:\n") + source ); } remove_marked_members: (inout this) = n*.type_remove_marked_members(); From d72a055311c4ed9f24c2e09581e4a807bf140802 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Fri, 15 Dec 2023 18:49:30 -1000 Subject: [PATCH 07/10] Restore preconditions for `add_initializer` And: - Add proper early returns for failed null checks - Disable the `contract_group` default constructor, since we aren't checking the handler before trying to invoke it. --- include/cpp2util.h | 2 +- source/reflect.h | 305 ++++++++++++++++++++++++--------------------- source/reflect.h2 | 47 ++++--- 3 files changed, 200 insertions(+), 154 deletions(-) diff --git a/include/cpp2util.h b/include/cpp2util.h index 302c55a754..2c9c9c9259 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -386,7 +386,7 @@ class contract_group { public: using handler = void (*)(CPP2_MESSAGE_PARAM msg CPP2_SOURCE_LOCATION_PARAM); - constexpr contract_group (handler h = {}) : reporter(h) { } + constexpr contract_group (handler h) : reporter{h} { } constexpr auto set_handler(handler h); constexpr auto get_handler() const -> handler { return reporter; } constexpr auto expects (bool b, CPP2_MESSAGE_PARAM msg = "" CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) diff --git a/source/reflect.h b/source/reflect.h index a28d0e2ef9..656c805a6c 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -18,28 +18,28 @@ namespace meta { #line 32 "reflect.h2" class compiler_services; -#line 198 "reflect.h2" +#line 210 "reflect.h2" class declaration_base; -#line 224 "reflect.h2" +#line 236 "reflect.h2" class declaration; -#line 306 "reflect.h2" +#line 318 "reflect.h2" class function_declaration; -#line 388 "reflect.h2" +#line 404 "reflect.h2" class object_declaration; -#line 424 "reflect.h2" +#line 440 "reflect.h2" class type_declaration; -#line 556 "reflect.h2" +#line 575 "reflect.h2" class alias_declaration; -#line 895 "reflect.h2" +#line 914 "reflect.h2" class value_member_info; -#line 1389 "reflect.h2" +#line 1408 "reflect.h2" } } @@ -82,6 +82,12 @@ namespace meta { class compiler_services { + // Enable custom contracts on this object, to use .require + // + public: auto expects(auto const& b, auto const& msg) const& -> void; + + // Common data members + // private: std::vector* errors; private: int errors_original_size; private: std::deque* generated_tokens; @@ -90,24 +96,28 @@ class compiler_services private: std::vector metafunction_args {}; private: bool metafunctions_used {false}; + // Constructor + // public: explicit compiler_services( std::vector* errors_, std::deque* generated_tokens_ ); -#line 54 "reflect.h2" +#line 62 "reflect.h2" + // Common API + // public: auto set_metafunction_name(cpp2::in name, cpp2::in> args) & -> void; -#line 60 "reflect.h2" +#line 70 "reflect.h2" public: [[nodiscard]] auto get_metafunction_name() const& -> std::string_view; public: [[nodiscard]] auto get_argument(cpp2::in index) & -> std::string; -#line 70 "reflect.h2" +#line 80 "reflect.h2" public: [[nodiscard]] auto get_arguments() & -> std::vector; -#line 75 "reflect.h2" +#line 85 "reflect.h2" public: [[nodiscard]] auto arguments_were_used() const& -> bool; protected: [[nodiscard]] auto parse_statement( @@ -115,23 +125,25 @@ class compiler_services std::string_view source ) & -> std::unique_ptr; -#line 125 "reflect.h2" +#line 135 "reflect.h2" public: [[nodiscard]] virtual auto position() const -> source_position; -#line 131 "reflect.h2" +#line 141 "reflect.h2" + // Error diagnosis and handling, integrated with compiler output + // public: auto require( cpp2::in b, cpp2::in msg ) const& -> void; -#line 142 "reflect.h2" +#line 154 "reflect.h2" public: auto error(cpp2::in msg) const& -> void; public: virtual ~compiler_services() noexcept; public: compiler_services(compiler_services const& that); -#line 150 "reflect.h2" +#line 162 "reflect.h2" }; /* @@ -170,7 +182,7 @@ type_id: @polymorphic_base @copyable type = } */ -#line 189 "reflect.h2" +#line 201 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -183,7 +195,7 @@ type_id: @polymorphic_base @copyable type = class declaration_base : public compiler_services { -#line 202 "reflect.h2" +#line 214 "reflect.h2" protected: declaration_node* n; protected: explicit declaration_base( @@ -192,31 +204,31 @@ class declaration_base cpp2::in s ); -#line 215 "reflect.h2" +#line 227 "reflect.h2" public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; public: virtual ~declaration_base() noexcept; public: declaration_base(declaration_base const& that); -#line 218 "reflect.h2" +#line 230 "reflect.h2" }; -#line 221 "reflect.h2" +#line 233 "reflect.h2" //----------------------------------------------------------------------- // All declarations // class declaration : public declaration_base { -#line 228 "reflect.h2" +#line 240 "reflect.h2" public: explicit declaration( declaration_node* n_, cpp2::in s ); -#line 237 "reflect.h2" +#line 249 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -235,7 +247,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 258 "reflect.h2" +#line 270 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto is_global() const& -> bool; @@ -278,24 +290,24 @@ public: declaration(declaration const& that); // this precondition should be sufficient ... -#line 300 "reflect.h2" +#line 312 "reflect.h2" }; -#line 303 "reflect.h2" +#line 315 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 310 "reflect.h2" +#line 322 "reflect.h2" public: explicit function_declaration( declaration_node* n_, cpp2::in s ); -#line 320 "reflect.h2" +#line 332 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const& -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const& -> bool; @@ -331,7 +343,7 @@ class function_declaration public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 363 "reflect.h2" +#line 375 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -342,103 +354,103 @@ class function_declaration public: function_declaration(function_declaration const& that); -#line 382 "reflect.h2" +#line 398 "reflect.h2" }; -#line 385 "reflect.h2" +#line 401 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 392 "reflect.h2" +#line 408 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 402 "reflect.h2" +#line 418 "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 412 "reflect.h2" +#line 428 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 418 "reflect.h2" +#line 434 "reflect.h2" }; -#line 421 "reflect.h2" +#line 437 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 428 "reflect.h2" +#line 444 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 438 "reflect.h2" +#line 454 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 450 "reflect.h2" +#line 466 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 465 "reflect.h2" +#line 481 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 480 "reflect.h2" +#line 496 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 490 "reflect.h2" +#line 506 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 500 "reflect.h2" +#line 516 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 510 "reflect.h2" +#line 526 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 520 "reflect.h2" +#line 536 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 535 "reflect.h2" +#line 551 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 546 "reflect.h2" +#line 565 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 550 "reflect.h2" +#line 569 "reflect.h2" }; -#line 553 "reflect.h2" +#line 572 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 560 "reflect.h2" +#line 579 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -447,10 +459,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 569 "reflect.h2" +#line 588 "reflect.h2" }; -#line 572 "reflect.h2" +#line 591 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -465,7 +477,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 590 "reflect.h2" +#line 609 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -480,7 +492,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 629 "reflect.h2" +#line 648 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -502,7 +514,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 673 "reflect.h2" +#line 692 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -528,7 +540,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 717 "reflect.h2" +#line 736 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -536,19 +548,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 727 "reflect.h2" +#line 746 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 735 "reflect.h2" +#line 754 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 744 "reflect.h2" +#line 763 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -567,7 +579,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 781 "reflect.h2" +#line 800 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -577,7 +589,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 806 "reflect.h2" +#line 825 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -590,13 +602,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 822 "reflect.h2" +#line 841 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 828 "reflect.h2" +#line 847 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 835 "reflect.h2" +#line 854 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -624,7 +636,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 878 "reflect.h2" +#line 897 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -654,7 +666,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1070 "reflect.h2" +#line 1089 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -666,7 +678,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1096 "reflect.h2" +#line 1115 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -679,7 +691,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1128 "reflect.h2" +#line 1147 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -706,14 +718,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1275 "reflect.h2" +#line 1294 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1285 "reflect.h2" +#line 1304 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -724,7 +736,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1389 "reflect.h2" +#line 1408 "reflect.h2" } } @@ -739,7 +751,10 @@ namespace cpp2 { namespace meta { -#line 42 "reflect.h2" +#line 36 "reflect.h2" + auto compiler_services::expects(auto const& b, auto const& msg) const& -> void { require(b, msg); } + +#line 50 "reflect.h2" compiler_services::compiler_services( std::vector* errors_, @@ -749,12 +764,13 @@ namespace meta { , errors_original_size{ cpp2::unsafe_narrow(std::ssize(*cpp2::assert_not_null(errors))) } , generated_tokens{ generated_tokens_ } , parser{ *cpp2::assert_not_null(errors) } -#line 47 "reflect.h2" +#line 55 "reflect.h2" { -#line 52 "reflect.h2" +#line 60 "reflect.h2" } +#line 64 "reflect.h2" auto compiler_services::set_metafunction_name(cpp2::in name, cpp2::in> args) & -> void{ metafunction_name = name; metafunction_args = args; @@ -796,7 +812,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // -#line 93 "reflect.h2" +#line 103 "reflect.h2" if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos != source.npos) { @@ -809,7 +825,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); } } -#line 104 "reflect.h2" +#line 114 "reflect.h2" if (!(CPP2_UFCS(empty)(source))) { std::move(add_line)(std::move(source)); } @@ -837,6 +853,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); return { }; } +#line 143 "reflect.h2" auto compiler_services::require( cpp2::in b, @@ -867,7 +884,7 @@ compiler_services::compiler_services(compiler_services const& that) , metafunction_args{ that.metafunction_args } , metafunctions_used{ that.metafunctions_used }{} -#line 204 "reflect.h2" +#line 216 "reflect.h2" declaration_base::declaration_base( declaration_node* n_, @@ -875,10 +892,10 @@ compiler_services::compiler_services(compiler_services const& that) ) : compiler_services{ s } , n{ n_ } -#line 209 "reflect.h2" +#line 221 "reflect.h2" { -#line 212 "reflect.h2" +#line 224 "reflect.h2" cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } @@ -891,14 +908,14 @@ declaration_base::declaration_base(declaration_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} -#line 228 "reflect.h2" +#line 240 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::in s ) : declaration_base{ n_, s } -#line 233 "reflect.h2" +#line 245 "reflect.h2" { } @@ -964,7 +981,7 @@ declaration_base::declaration_base(declaration_base const& that) { cpp2::Type.expects(parent_is_type(), ""); -#line 297 "reflect.h2" +#line 309 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -973,14 +990,14 @@ declaration_base::declaration_base(declaration_base const& that) declaration::declaration(declaration const& that) : declaration_base{ static_cast(that) }{} -#line 310 "reflect.h2" +#line 322 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 315 "reflect.h2" +#line 327 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); @@ -1036,30 +1053,37 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::make_virtual() & -> bool { return CPP2_UFCS(make_function_virtual)((*cpp2::assert_not_null(n))); } auto function_declaration::add_initializer(cpp2::in source) & -> void - { - require(!(has_initializer()), - "cannot add an initializer to a function that already has one"); - require(parent_is_type(), - "cannot add an initializer to a function that isn't in a type scope"); +#line 384 "reflect.h2" + { + (*this).expects(!(has_initializer()), "cannot add an initializer to a function that already has one"); + (*this).expects(parent_is_type(), "cannot add an initializer to a function that isn't in a type scope"); + //require( !has_initializer(), + // "cannot add an initializer to a function that already has one"); + //require( parent_is_type(), + // "cannot add an initializer to a function that isn't in a type scope"); + +#line 390 "reflect.h2" auto stmt {parse_statement(source)}; - require(cpp2::as_(stmt), - std::string("cannot add an initializer that is not a valid statement: ") + source); + if (!((cpp2::as_(stmt)))) { + error(std::string("cannot add an initializer that is not a valid statement: ") + source); + return ; + } require(CPP2_UFCS(add_function_initializer)((*cpp2::assert_not_null(n)), std::move(stmt)), - std::string("error attempting to add initializer:\n") + source); + std::string("unexpected error while attempting to add initializer:\n") + source); } function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 392 "reflect.h2" +#line 408 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 397 "reflect.h2" +#line 413 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1085,14 +1109,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 428 "reflect.h2" +#line 444 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 433 "reflect.h2" +#line 449 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1182,13 +1206,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 527 "reflect.h2" +#line 543 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 528 "reflect.h2" +#line 544 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1199,12 +1223,15 @@ declaration::declaration(declaration const& that) auto type_declaration::add_member(cpp2::in source) & -> void { auto decl {parse_statement(source)}; - require(cpp2::as_(decl), - "the provided source string is not a valid statement"); - require(CPP2_UFCS(is_declaration)((*cpp2::assert_not_null(decl))), - "cannot add a member that is not a declaration"); + if (!((cpp2::as_(decl)))) { + error("the provided source string is not a valid statement"); + return ; + } + if (!(CPP2_UFCS(is_declaration)((*cpp2::assert_not_null(decl))))) { + error("cannot add a member that is not a declaration"); + } require(CPP2_UFCS(add_type_member)((*cpp2::assert_not_null(n)), std::move(decl)), - std::string("error attempting to add member:\n") + source); + std::string("unexpected error while attempting to add member:\n") + source); } auto type_declaration::remove_marked_members() & -> void { CPP2_UFCS(type_remove_marked_members)((*cpp2::assert_not_null(n))); } @@ -1215,14 +1242,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 560 "reflect.h2" +#line 579 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 565 "reflect.h2" +#line 584 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1231,13 +1258,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 584 "reflect.h2" +#line 603 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 602 "reflect.h2" +#line 621 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1264,7 +1291,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 648 "reflect.h2" +#line 667 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1289,7 +1316,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 693 "reflect.h2" +#line 712 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1314,25 +1341,25 @@ auto ordered_impl( } } -#line 722 "reflect.h2" +#line 741 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 730 "reflect.h2" +#line 749 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 738 "reflect.h2" +#line 757 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 760 "reflect.h2" +#line 779 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1354,7 +1381,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 788 "reflect.h2" +#line 807 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1373,7 +1400,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 816 "reflect.h2" +#line 835 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1392,7 +1419,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 860 "reflect.h2" +#line 879 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1410,7 +1437,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 901 "reflect.h2" +#line 920 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1435,7 +1462,7 @@ auto basic_enum( { std::string value = "-1"; -#line 924 "reflect.h2" +#line 943 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1474,7 +1501,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 961 "reflect.h2" +#line 980 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1514,7 +1541,7 @@ std::string value = "-1"; } } -#line 1001 "reflect.h2" +#line 1020 "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' @@ -1553,7 +1580,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1037 "reflect.h2" +#line 1056 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1585,10 +1612,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1067 "reflect.h2" +#line 1086 "reflect.h2" } -#line 1079 "reflect.h2" +#line 1098 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1605,7 +1632,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1106 "reflect.h2" +#line 1125 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1627,7 +1654,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1152 "reflect.h2" +#line 1171 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1636,7 +1663,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1159 "reflect.h2" +#line 1178 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1661,7 +1688,7 @@ auto value = 0; } while (false); ++value; } } -#line 1182 "reflect.h2" +#line 1201 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1676,7 +1703,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1197 "reflect.h2" +#line 1216 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1685,12 +1712,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1289 "reflect.h2" +#line 1308 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1880,7 +1907,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1389 "reflect.h2" +#line 1408 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 258f82316f..c6b2fae3f5 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -31,6 +31,12 @@ meta: namespace = { compiler_services: @polymorphic_base @copyable type = { + // Enable custom contracts on this object, to use .require + // + expects:(this, b, msg) = require(b, msg); + + // Common data members + // errors : *std::vector; errors_original_size : int; generated_tokens : *std::deque; @@ -39,6 +45,8 @@ compiler_services: @polymorphic_base @copyable type = metafunction_args : std::vector = (); metafunctions_used : bool = false; + // Constructor + // operator=: ( out this, errors_ : *std::vector, @@ -51,6 +59,8 @@ compiler_services: @polymorphic_base @copyable type = parser = errors*; } + // Common API + // set_metafunction_name: (inout this, name: std::string_view, args: std::vector) = { metafunction_name = name; metafunction_args = args; @@ -128,10 +138,12 @@ compiler_services: @polymorphic_base @copyable type = return (); } + // Error diagnosis and handling, integrated with compiler output + // require:( this, - b: bool, - msg: std::string_view + b : bool, + msg : std::string_view ) = { if !b { @@ -367,17 +379,21 @@ function_declaration: @copyable type = make_virtual : (inout this) -> bool = n*.make_function_virtual(); add_initializer: (inout this, source: std::string_view) + pre (!has_initializer(), "cannot add an initializer to a function that already has one") + pre (parent_is_type(), "cannot add an initializer to a function that isn't in a type scope") = { - require( !has_initializer(), - "cannot add an initializer to a function that already has one"); - require( parent_is_type(), - "cannot add an initializer to a function that isn't in a type scope"); + //require( !has_initializer(), + // "cannot add an initializer to a function that already has one"); + //require( parent_is_type(), + // "cannot add an initializer to a function that isn't in a type scope"); stmt := parse_statement(source); - require( stmt as bool, - std::string("cannot add an initializer that is not a valid statement: ") + source); + if !(stmt as bool) { + error( std::string("cannot add an initializer that is not a valid statement: ") + source ); + return; + } require (n*.add_function_initializer(stmt), - std::string("error attempting to add initializer:\n") + source); + std::string("unexpected error while attempting to add initializer:\n") + source); } } @@ -535,12 +551,15 @@ type_declaration: @copyable type = add_member: (inout this, source: std::string_view) = { decl := parse_statement(source); - require( decl as bool, - "the provided source string is not a valid statement"); - require( decl*.is_declaration(), - "cannot add a member that is not a declaration"); + if !(decl as bool) { + error("the provided source string is not a valid statement"); + return; + } + if !decl*.is_declaration() { + error("cannot add a member that is not a declaration"); + } require( n*.add_type_member(decl), - std::string("error attempting to add member:\n") + source ); + std::string("unexpected error while attempting to add member:\n") + source ); } remove_marked_members: (inout this) = n*.type_remove_marked_members(); From 6c2b4341fae1109860cc6ff16127a3d522f4b98d Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 16 Dec 2023 10:27:25 -1000 Subject: [PATCH 08/10] Second review: Add graceful termination for a metafunction precondition violation And restore `source` string to error output, and make it just come out routinely as soon as a parse error is detected --- source/reflect.h | 306 ++++++++++++++++++++++++---------------------- source/reflect.h2 | 30 +++-- 2 files changed, 177 insertions(+), 159 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 656c805a6c..4a9de15bfc 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -18,28 +18,28 @@ namespace meta { #line 32 "reflect.h2" class compiler_services; -#line 210 "reflect.h2" +#line 216 "reflect.h2" class declaration_base; -#line 236 "reflect.h2" +#line 242 "reflect.h2" class declaration; -#line 318 "reflect.h2" +#line 324 "reflect.h2" class function_declaration; -#line 404 "reflect.h2" +#line 410 "reflect.h2" class object_declaration; -#line 440 "reflect.h2" +#line 446 "reflect.h2" class type_declaration; -#line 575 "reflect.h2" +#line 581 "reflect.h2" class alias_declaration; -#line 914 "reflect.h2" +#line 920 "reflect.h2" class value_member_info; -#line 1408 "reflect.h2" +#line 1414 "reflect.h2" } } @@ -82,10 +82,6 @@ namespace meta { class compiler_services { - // Enable custom contracts on this object, to use .require - // - public: auto expects(auto const& b, auto const& msg) const& -> void; - // Common data members // private: std::vector* errors; @@ -104,31 +100,34 @@ class compiler_services std::deque* generated_tokens_ ); -#line 62 "reflect.h2" +#line 58 "reflect.h2" // Common API // public: auto set_metafunction_name(cpp2::in name, cpp2::in> args) & -> void; -#line 70 "reflect.h2" +#line 66 "reflect.h2" public: [[nodiscard]] auto get_metafunction_name() const& -> std::string_view; public: [[nodiscard]] auto get_argument(cpp2::in index) & -> std::string; -#line 80 "reflect.h2" +#line 76 "reflect.h2" public: [[nodiscard]] auto get_arguments() & -> std::vector; -#line 85 "reflect.h2" +#line 81 "reflect.h2" public: [[nodiscard]] auto arguments_were_used() const& -> bool; +using parse_statement_ret = std::unique_ptr; + +#line 83 "reflect.h2" protected: [[nodiscard]] auto parse_statement( std::string_view source - ) & -> std::unique_ptr; + ) & -> parse_statement_ret; -#line 135 "reflect.h2" +#line 134 "reflect.h2" public: [[nodiscard]] virtual auto position() const -> source_position; -#line 141 "reflect.h2" +#line 140 "reflect.h2" // Error diagnosis and handling, integrated with compiler output // public: auto require( @@ -137,13 +136,18 @@ class compiler_services cpp2::in msg ) const& -> void; -#line 154 "reflect.h2" +#line 153 "reflect.h2" public: auto error(cpp2::in msg) const& -> void; + +#line 162 "reflect.h2" + // Enable custom contracts on this object + // + public: auto expects(auto const& b, auto const& msg) const& -> void; public: virtual ~compiler_services() noexcept; public: compiler_services(compiler_services const& that); -#line 162 "reflect.h2" +#line 168 "reflect.h2" }; /* @@ -182,7 +186,7 @@ type_id: @polymorphic_base @copyable type = } */ -#line 201 "reflect.h2" +#line 207 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -195,7 +199,7 @@ type_id: @polymorphic_base @copyable type = class declaration_base : public compiler_services { -#line 214 "reflect.h2" +#line 220 "reflect.h2" protected: declaration_node* n; protected: explicit declaration_base( @@ -204,31 +208,31 @@ class declaration_base cpp2::in s ); -#line 227 "reflect.h2" +#line 233 "reflect.h2" public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; public: virtual ~declaration_base() noexcept; public: declaration_base(declaration_base const& that); -#line 230 "reflect.h2" +#line 236 "reflect.h2" }; -#line 233 "reflect.h2" +#line 239 "reflect.h2" //----------------------------------------------------------------------- // All declarations // class declaration : public declaration_base { -#line 240 "reflect.h2" +#line 246 "reflect.h2" public: explicit declaration( declaration_node* n_, cpp2::in s ); -#line 249 "reflect.h2" +#line 255 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -247,7 +251,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 270 "reflect.h2" +#line 276 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto is_global() const& -> bool; @@ -290,24 +294,24 @@ public: declaration(declaration const& that); // this precondition should be sufficient ... -#line 312 "reflect.h2" +#line 318 "reflect.h2" }; -#line 315 "reflect.h2" +#line 321 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 322 "reflect.h2" +#line 328 "reflect.h2" public: explicit function_declaration( declaration_node* n_, cpp2::in s ); -#line 332 "reflect.h2" +#line 338 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const& -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const& -> bool; @@ -343,7 +347,7 @@ class function_declaration public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 375 "reflect.h2" +#line 381 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -354,103 +358,103 @@ class function_declaration public: function_declaration(function_declaration const& that); -#line 398 "reflect.h2" +#line 404 "reflect.h2" }; -#line 401 "reflect.h2" +#line 407 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 408 "reflect.h2" +#line 414 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 418 "reflect.h2" +#line 424 "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 428 "reflect.h2" +#line 434 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 434 "reflect.h2" +#line 440 "reflect.h2" }; -#line 437 "reflect.h2" +#line 443 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 444 "reflect.h2" +#line 450 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 454 "reflect.h2" +#line 460 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 466 "reflect.h2" +#line 472 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 481 "reflect.h2" +#line 487 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 496 "reflect.h2" +#line 502 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 506 "reflect.h2" +#line 512 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 516 "reflect.h2" +#line 522 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 526 "reflect.h2" +#line 532 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 536 "reflect.h2" +#line 542 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 551 "reflect.h2" +#line 557 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 565 "reflect.h2" +#line 571 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 569 "reflect.h2" +#line 575 "reflect.h2" }; -#line 572 "reflect.h2" +#line 578 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 579 "reflect.h2" +#line 585 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -459,10 +463,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 588 "reflect.h2" +#line 594 "reflect.h2" }; -#line 591 "reflect.h2" +#line 597 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -477,7 +481,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 609 "reflect.h2" +#line 615 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -492,7 +496,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 648 "reflect.h2" +#line 654 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -514,7 +518,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 692 "reflect.h2" +#line 698 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -540,7 +544,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 736 "reflect.h2" +#line 742 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -548,19 +552,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 746 "reflect.h2" +#line 752 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 754 "reflect.h2" +#line 760 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 763 "reflect.h2" +#line 769 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -579,7 +583,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 800 "reflect.h2" +#line 806 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -589,7 +593,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 825 "reflect.h2" +#line 831 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -602,13 +606,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 841 "reflect.h2" +#line 847 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 847 "reflect.h2" +#line 853 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 854 "reflect.h2" +#line 860 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -636,7 +640,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 897 "reflect.h2" +#line 903 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -666,7 +670,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1089 "reflect.h2" +#line 1095 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -678,7 +682,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1115 "reflect.h2" +#line 1121 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -691,7 +695,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1147 "reflect.h2" +#line 1153 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -718,14 +722,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1294 "reflect.h2" +#line 1300 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1304 "reflect.h2" +#line 1310 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -736,7 +740,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1408 "reflect.h2" +#line 1414 "reflect.h2" } } @@ -751,10 +755,7 @@ namespace cpp2 { namespace meta { -#line 36 "reflect.h2" - auto compiler_services::expects(auto const& b, auto const& msg) const& -> void { require(b, msg); } - -#line 50 "reflect.h2" +#line 46 "reflect.h2" compiler_services::compiler_services( std::vector* errors_, @@ -764,13 +765,13 @@ namespace meta { , errors_original_size{ cpp2::unsafe_narrow(std::ssize(*cpp2::assert_not_null(errors))) } , generated_tokens{ generated_tokens_ } , parser{ *cpp2::assert_not_null(errors) } -#line 55 "reflect.h2" +#line 51 "reflect.h2" { -#line 60 "reflect.h2" +#line 56 "reflect.h2" } -#line 64 "reflect.h2" +#line 60 "reflect.h2" auto compiler_services::set_metafunction_name(cpp2::in name, cpp2::in> args) & -> void{ metafunction_name = name; metafunction_args = args; @@ -797,9 +798,11 @@ namespace meta { [[nodiscard]] auto compiler_services::parse_statement( std::string_view source - ) & -> std::unique_ptr + ) & -> parse_statement_ret { + cpp2::deferred_init> ret; +#line 89 "reflect.h2" CPP2_UFCS(push_back)(generated_lines, std::vector()); auto lines {&CPP2_UFCS(back)(generated_lines)}; @@ -812,7 +815,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // -#line 103 "reflect.h2" +#line 99 "reflect.h2" if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos != source.npos) { @@ -825,9 +828,9 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); } } -#line 114 "reflect.h2" +#line 110 "reflect.h2" if (!(CPP2_UFCS(empty)(source))) { - std::move(add_line)(std::move(source)); + std::move(add_line)(source); } // Now lex this source fragment to generate @@ -841,10 +844,13 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // Now parse this single declaration from // the lexed tokens - return CPP2_UFCS(parse_one_declaration)(parser, - (*cpp2::assert_not_null(CPP2_UFCS(begin)(CPP2_UFCS(get_map)(*cpp2::assert_not_null(std::move(tokens)))))).second, - *cpp2::assert_not_null(generated_tokens) - ); + ret.construct(CPP2_UFCS(parse_one_declaration)(parser, + (*cpp2::assert_not_null(CPP2_UFCS(begin)(CPP2_UFCS(get_map)(*cpp2::assert_not_null(std::move(tokens)))))).second, + *cpp2::assert_not_null(generated_tokens) + )); + if (!(ret.value())) { + error("parse failed - the source string is not a valid statement:\n" + cpp2::to_string(std::move(source))); + }return std::move(ret.value()); } [[nodiscard]] auto compiler_services::position() const -> source_position @@ -853,7 +859,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); return { }; } -#line 143 "reflect.h2" +#line 142 "reflect.h2" auto compiler_services::require( cpp2::in b, @@ -869,11 +875,17 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); { auto message {cpp2::as_(msg)}; if (!(CPP2_UFCS(empty)(metafunction_name))) { - message = "while applying @" + metafunction_name + " - " + message; + message = "while applying @" + cpp2::to_string(metafunction_name) + " - " + cpp2::to_string(message); } static_cast(CPP2_UFCS(emplace_back)((*cpp2::assert_not_null(errors)), position(), std::move(message))); } +#line 164 "reflect.h2" + auto compiler_services::expects(auto const& b, auto const& msg) const& -> void{ + require(b, msg); + if (!(b)) {throw(std::runtime_error(" ==> programming bug found in metafunction @" + cpp2::to_string(metafunction_name) + " - precondition violation - see previous errors")); } + } + compiler_services::~compiler_services() noexcept{} compiler_services::compiler_services(compiler_services const& that) : errors{ that.errors } @@ -884,7 +896,7 @@ compiler_services::compiler_services(compiler_services const& that) , metafunction_args{ that.metafunction_args } , metafunctions_used{ that.metafunctions_used }{} -#line 216 "reflect.h2" +#line 222 "reflect.h2" declaration_base::declaration_base( declaration_node* n_, @@ -892,10 +904,10 @@ compiler_services::compiler_services(compiler_services const& that) ) : compiler_services{ s } , n{ n_ } -#line 221 "reflect.h2" +#line 227 "reflect.h2" { -#line 224 "reflect.h2" +#line 230 "reflect.h2" cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } @@ -908,14 +920,14 @@ declaration_base::declaration_base(declaration_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} -#line 240 "reflect.h2" +#line 246 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::in s ) : declaration_base{ n_, s } -#line 245 "reflect.h2" +#line 251 "reflect.h2" { } @@ -981,7 +993,7 @@ declaration_base::declaration_base(declaration_base const& that) { cpp2::Type.expects(parent_is_type(), ""); -#line 309 "reflect.h2" +#line 315 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -990,14 +1002,14 @@ declaration_base::declaration_base(declaration_base const& that) declaration::declaration(declaration const& that) : declaration_base{ static_cast(that) }{} -#line 322 "reflect.h2" +#line 328 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 327 "reflect.h2" +#line 333 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); @@ -1054,7 +1066,7 @@ declaration::declaration(declaration const& that) auto function_declaration::add_initializer(cpp2::in source) & -> void -#line 384 "reflect.h2" +#line 390 "reflect.h2" { (*this).expects(!(has_initializer()), "cannot add an initializer to a function that already has one"); (*this).expects(parent_is_type(), "cannot add an initializer to a function that isn't in a type scope"); @@ -1063,27 +1075,27 @@ declaration::declaration(declaration const& that) //require( parent_is_type(), // "cannot add an initializer to a function that isn't in a type scope"); -#line 390 "reflect.h2" +#line 396 "reflect.h2" auto stmt {parse_statement(source)}; if (!((cpp2::as_(stmt)))) { - error(std::string("cannot add an initializer that is not a valid statement: ") + source); + error("cannot add an initializer that is not a valid statement"); return ; } require(CPP2_UFCS(add_function_initializer)((*cpp2::assert_not_null(n)), std::move(stmt)), - std::string("unexpected error while attempting to add initializer:\n") + source); + std::string("unexpected error while attempting to add initializer")); } function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 408 "reflect.h2" +#line 414 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 413 "reflect.h2" +#line 419 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1109,14 +1121,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 444 "reflect.h2" +#line 450 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 449 "reflect.h2" +#line 455 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1206,13 +1218,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 543 "reflect.h2" +#line 549 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 544 "reflect.h2" +#line 550 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1242,14 +1254,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 579 "reflect.h2" +#line 585 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 584 "reflect.h2" +#line 590 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1258,13 +1270,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 603 "reflect.h2" +#line 609 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 621 "reflect.h2" +#line 627 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1291,7 +1303,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 667 "reflect.h2" +#line 673 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1316,7 +1328,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 712 "reflect.h2" +#line 718 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1341,25 +1353,25 @@ auto ordered_impl( } } -#line 741 "reflect.h2" +#line 747 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 749 "reflect.h2" +#line 755 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 757 "reflect.h2" +#line 763 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 779 "reflect.h2" +#line 785 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1381,7 +1393,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 807 "reflect.h2" +#line 813 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1400,7 +1412,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 835 "reflect.h2" +#line 841 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1419,7 +1431,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 879 "reflect.h2" +#line 885 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1437,7 +1449,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 920 "reflect.h2" +#line 926 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1462,7 +1474,7 @@ auto basic_enum( { std::string value = "-1"; -#line 943 "reflect.h2" +#line 949 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1501,7 +1513,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 980 "reflect.h2" +#line 986 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1541,7 +1553,7 @@ std::string value = "-1"; } } -#line 1020 "reflect.h2" +#line 1026 "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' @@ -1580,7 +1592,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1056 "reflect.h2" +#line 1062 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1612,10 +1624,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1086 "reflect.h2" +#line 1092 "reflect.h2" } -#line 1098 "reflect.h2" +#line 1104 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1632,7 +1644,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1125 "reflect.h2" +#line 1131 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1654,7 +1666,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1171 "reflect.h2" +#line 1177 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1663,7 +1675,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1178 "reflect.h2" +#line 1184 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1688,7 +1700,7 @@ auto value = 0; } while (false); ++value; } } -#line 1201 "reflect.h2" +#line 1207 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1703,7 +1715,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1216 "reflect.h2" +#line 1222 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1712,12 +1724,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1308 "reflect.h2" +#line 1314 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1907,7 +1919,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1408 "reflect.h2" +#line 1414 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index c6b2fae3f5..c55f4780a4 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -31,10 +31,6 @@ meta: namespace = { compiler_services: @polymorphic_base @copyable type = { - // Enable custom contracts on this object, to use .require - // - expects:(this, b, msg) = require(b, msg); - // Common data members // errors : *std::vector; @@ -88,7 +84,7 @@ compiler_services: @polymorphic_base @copyable type = inout this, copy source: std::string_view ) - -> std::unique_ptr + -> (ret: std::unique_ptr) = { generated_lines.push_back( std::vector() ); lines := generated_lines.back()&; @@ -126,10 +122,13 @@ compiler_services: @polymorphic_base @copyable type = // Now parse this single declaration from // the lexed tokens - return parser.parse_one_declaration( - tokens*.get_map().begin()*.second, - generated_tokens* - ); + ret = parser.parse_one_declaration( + tokens*.get_map().begin()*.second, + generated_tokens* + ); + if !ret { + error( "parse failed - the source string is not a valid statement:\n(source)$"); + } } position: (virtual this) @@ -155,10 +154,17 @@ compiler_services: @polymorphic_base @copyable type = = { message := msg as std::string; if !metafunction_name.empty() { - message = "while applying @" + metafunction_name + " - " + message; + message = "while applying @(metafunction_name)$ - (message)$"; } _ = errors*.emplace_back( position(), message); } + + // Enable custom contracts on this object + // + expects:(this, b, msg) = { + require(b, msg); + if !b { throw( std::runtime_error(" ==> programming bug found in metafunction @(metafunction_name)$ - precondition violation - see previous errors") ); } + } } /* @@ -389,11 +395,11 @@ function_declaration: @copyable type = stmt := parse_statement(source); if !(stmt as bool) { - error( std::string("cannot add an initializer that is not a valid statement: ") + source ); + error( "cannot add an initializer that is not a valid statement"); return; } require (n*.add_function_initializer(stmt), - std::string("unexpected error while attempting to add initializer:\n") + source); + std::string("unexpected error while attempting to add initializer")); } } From 3813b4615add7918b089e2939b9cac9630bcedb5 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 16 Dec 2023 11:19:53 -1000 Subject: [PATCH 09/10] Report original source string on parse errors --- source/reflect.h | 254 +++++++++++++++++++++++----------------------- source/reflect.h2 | 4 +- 2 files changed, 131 insertions(+), 127 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index 4a9de15bfc..f57f7c2bf9 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -18,28 +18,28 @@ namespace meta { #line 32 "reflect.h2" class compiler_services; -#line 216 "reflect.h2" +#line 218 "reflect.h2" class declaration_base; -#line 242 "reflect.h2" +#line 244 "reflect.h2" class declaration; -#line 324 "reflect.h2" +#line 326 "reflect.h2" class function_declaration; -#line 410 "reflect.h2" +#line 412 "reflect.h2" class object_declaration; -#line 446 "reflect.h2" +#line 448 "reflect.h2" class type_declaration; -#line 581 "reflect.h2" +#line 583 "reflect.h2" class alias_declaration; -#line 920 "reflect.h2" +#line 922 "reflect.h2" class value_member_info; -#line 1414 "reflect.h2" +#line 1416 "reflect.h2" } } @@ -124,10 +124,10 @@ using parse_statement_ret = std::unique_ptr; std::string_view source ) & -> parse_statement_ret; -#line 134 "reflect.h2" +#line 136 "reflect.h2" public: [[nodiscard]] virtual auto position() const -> source_position; -#line 140 "reflect.h2" +#line 142 "reflect.h2" // Error diagnosis and handling, integrated with compiler output // public: auto require( @@ -136,10 +136,10 @@ using parse_statement_ret = std::unique_ptr; cpp2::in msg ) const& -> void; -#line 153 "reflect.h2" +#line 155 "reflect.h2" public: auto error(cpp2::in msg) const& -> void; -#line 162 "reflect.h2" +#line 164 "reflect.h2" // Enable custom contracts on this object // public: auto expects(auto const& b, auto const& msg) const& -> void; @@ -147,7 +147,7 @@ using parse_statement_ret = std::unique_ptr; public: compiler_services(compiler_services const& that); -#line 168 "reflect.h2" +#line 170 "reflect.h2" }; /* @@ -186,7 +186,7 @@ type_id: @polymorphic_base @copyable type = } */ -#line 207 "reflect.h2" +#line 209 "reflect.h2" //----------------------------------------------------------------------- // // Declarations @@ -199,7 +199,7 @@ type_id: @polymorphic_base @copyable type = class declaration_base : public compiler_services { -#line 220 "reflect.h2" +#line 222 "reflect.h2" protected: declaration_node* n; protected: explicit declaration_base( @@ -208,31 +208,31 @@ class declaration_base cpp2::in s ); -#line 233 "reflect.h2" +#line 235 "reflect.h2" public: [[nodiscard]] auto position() const -> source_position override; public: [[nodiscard]] auto print() const& -> std::string; public: virtual ~declaration_base() noexcept; public: declaration_base(declaration_base const& that); -#line 236 "reflect.h2" +#line 238 "reflect.h2" }; -#line 239 "reflect.h2" +#line 241 "reflect.h2" //----------------------------------------------------------------------- // All declarations // class declaration : public declaration_base { -#line 246 "reflect.h2" +#line 248 "reflect.h2" public: explicit declaration( declaration_node* n_, cpp2::in s ); -#line 255 "reflect.h2" +#line 257 "reflect.h2" public: [[nodiscard]] auto is_public() const& -> bool; public: [[nodiscard]] auto is_protected() const& -> bool; public: [[nodiscard]] auto is_private() const& -> bool; @@ -251,7 +251,7 @@ class declaration public: [[nodiscard]] auto name() const& -> std::string_view; -#line 276 "reflect.h2" +#line 278 "reflect.h2" public: [[nodiscard]] auto has_initializer() const& -> bool; public: [[nodiscard]] auto is_global() const& -> bool; @@ -294,24 +294,24 @@ public: declaration(declaration const& that); // this precondition should be sufficient ... -#line 318 "reflect.h2" +#line 320 "reflect.h2" }; -#line 321 "reflect.h2" +#line 323 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 328 "reflect.h2" +#line 330 "reflect.h2" public: explicit function_declaration( declaration_node* n_, cpp2::in s ); -#line 338 "reflect.h2" +#line 340 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const& -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const& -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const& -> bool; @@ -347,7 +347,7 @@ class function_declaration public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 381 "reflect.h2" +#line 383 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -358,103 +358,103 @@ class function_declaration public: function_declaration(function_declaration const& that); -#line 404 "reflect.h2" +#line 406 "reflect.h2" }; -#line 407 "reflect.h2" +#line 409 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 414 "reflect.h2" +#line 416 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 424 "reflect.h2" +#line 426 "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 434 "reflect.h2" +#line 436 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 440 "reflect.h2" +#line 442 "reflect.h2" }; -#line 443 "reflect.h2" +#line 445 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 450 "reflect.h2" +#line 452 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 460 "reflect.h2" +#line 462 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 472 "reflect.h2" +#line 474 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 487 "reflect.h2" +#line 489 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 502 "reflect.h2" +#line 504 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 512 "reflect.h2" +#line 514 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 522 "reflect.h2" +#line 524 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 532 "reflect.h2" +#line 534 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 542 "reflect.h2" +#line 544 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 557 "reflect.h2" +#line 559 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 571 "reflect.h2" +#line 573 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 575 "reflect.h2" +#line 577 "reflect.h2" }; -#line 578 "reflect.h2" +#line 580 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 585 "reflect.h2" +#line 587 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -463,10 +463,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 594 "reflect.h2" +#line 596 "reflect.h2" }; -#line 597 "reflect.h2" +#line 599 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -481,7 +481,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 615 "reflect.h2" +#line 617 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -496,7 +496,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 654 "reflect.h2" +#line 656 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -518,7 +518,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 698 "reflect.h2" +#line 700 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -544,7 +544,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 742 "reflect.h2" +#line 744 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -552,19 +552,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 752 "reflect.h2" +#line 754 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 760 "reflect.h2" +#line 762 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 769 "reflect.h2" +#line 771 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -583,7 +583,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 806 "reflect.h2" +#line 808 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -593,7 +593,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 831 "reflect.h2" +#line 833 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -606,13 +606,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 847 "reflect.h2" +#line 849 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 853 "reflect.h2" +#line 855 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 860 "reflect.h2" +#line 862 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -640,7 +640,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 903 "reflect.h2" +#line 905 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -670,7 +670,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1095 "reflect.h2" +#line 1097 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -682,7 +682,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1121 "reflect.h2" +#line 1123 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -695,7 +695,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1153 "reflect.h2" +#line 1155 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -722,14 +722,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1300 "reflect.h2" +#line 1302 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1310 "reflect.h2" +#line 1312 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -740,7 +740,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1414 "reflect.h2" +#line 1416 "reflect.h2" } } @@ -803,6 +803,8 @@ namespace meta { { cpp2::deferred_init> ret; #line 89 "reflect.h2" + auto original_source {source}; + CPP2_UFCS(push_back)(generated_lines, std::vector()); auto lines {&CPP2_UFCS(back)(generated_lines)}; @@ -815,7 +817,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // -#line 99 "reflect.h2" +#line 101 "reflect.h2" if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos != source.npos) { @@ -828,9 +830,9 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); } } -#line 110 "reflect.h2" +#line 112 "reflect.h2" if (!(CPP2_UFCS(empty)(source))) { - std::move(add_line)(source); + std::move(add_line)(std::move(source)); } // Now lex this source fragment to generate @@ -849,7 +851,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); *cpp2::assert_not_null(generated_tokens) )); if (!(ret.value())) { - error("parse failed - the source string is not a valid statement:\n" + cpp2::to_string(std::move(source))); + error("parse failed - the source string is not a valid statement:\n" + cpp2::to_string(std::move(original_source))); }return std::move(ret.value()); } @@ -859,7 +861,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); return { }; } -#line 142 "reflect.h2" +#line 144 "reflect.h2" auto compiler_services::require( cpp2::in b, @@ -880,7 +882,7 @@ auto newline_pos = CPP2_UFCS(find)(source, '\n'); static_cast(CPP2_UFCS(emplace_back)((*cpp2::assert_not_null(errors)), position(), std::move(message))); } -#line 164 "reflect.h2" +#line 166 "reflect.h2" auto compiler_services::expects(auto const& b, auto const& msg) const& -> void{ require(b, msg); if (!(b)) {throw(std::runtime_error(" ==> programming bug found in metafunction @" + cpp2::to_string(metafunction_name) + " - precondition violation - see previous errors")); } @@ -896,7 +898,7 @@ compiler_services::compiler_services(compiler_services const& that) , metafunction_args{ that.metafunction_args } , metafunctions_used{ that.metafunctions_used }{} -#line 222 "reflect.h2" +#line 224 "reflect.h2" declaration_base::declaration_base( declaration_node* n_, @@ -904,10 +906,10 @@ compiler_services::compiler_services(compiler_services const& that) ) : compiler_services{ s } , n{ n_ } -#line 227 "reflect.h2" +#line 229 "reflect.h2" { -#line 230 "reflect.h2" +#line 232 "reflect.h2" cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } @@ -920,14 +922,14 @@ declaration_base::declaration_base(declaration_base const& that) : compiler_services{ static_cast(that) } , n{ that.n }{} -#line 246 "reflect.h2" +#line 248 "reflect.h2" declaration::declaration( declaration_node* n_, cpp2::in s ) : declaration_base{ n_, s } -#line 251 "reflect.h2" +#line 253 "reflect.h2" { } @@ -993,7 +995,7 @@ declaration_base::declaration_base(declaration_base const& that) { cpp2::Type.expects(parent_is_type(), ""); -#line 315 "reflect.h2" +#line 317 "reflect.h2" auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -1002,14 +1004,14 @@ declaration_base::declaration_base(declaration_base const& that) declaration::declaration(declaration const& that) : declaration_base{ static_cast(that) }{} -#line 328 "reflect.h2" +#line 330 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 333 "reflect.h2" +#line 335 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); @@ -1066,7 +1068,7 @@ declaration::declaration(declaration const& that) auto function_declaration::add_initializer(cpp2::in source) & -> void -#line 390 "reflect.h2" +#line 392 "reflect.h2" { (*this).expects(!(has_initializer()), "cannot add an initializer to a function that already has one"); (*this).expects(parent_is_type(), "cannot add an initializer to a function that isn't in a type scope"); @@ -1075,7 +1077,7 @@ declaration::declaration(declaration const& that) //require( parent_is_type(), // "cannot add an initializer to a function that isn't in a type scope"); -#line 396 "reflect.h2" +#line 398 "reflect.h2" auto stmt {parse_statement(source)}; if (!((cpp2::as_(stmt)))) { error("cannot add an initializer that is not a valid statement"); @@ -1088,14 +1090,14 @@ declaration::declaration(declaration const& that) function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 414 "reflect.h2" +#line 416 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 419 "reflect.h2" +#line 421 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1121,14 +1123,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 450 "reflect.h2" +#line 452 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 455 "reflect.h2" +#line 457 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1218,13 +1220,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 549 "reflect.h2" +#line 551 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 550 "reflect.h2" +#line 552 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1254,14 +1256,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 585 "reflect.h2" +#line 587 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 590 "reflect.h2" +#line 592 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1270,13 +1272,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 609 "reflect.h2" +#line 611 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 627 "reflect.h2" +#line 629 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1303,7 +1305,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 673 "reflect.h2" +#line 675 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1328,7 +1330,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 718 "reflect.h2" +#line 720 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1353,25 +1355,25 @@ auto ordered_impl( } } -#line 747 "reflect.h2" +#line 749 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 755 "reflect.h2" +#line 757 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 763 "reflect.h2" +#line 765 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 785 "reflect.h2" +#line 787 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1393,7 +1395,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 813 "reflect.h2" +#line 815 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1412,7 +1414,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 841 "reflect.h2" +#line 843 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1431,7 +1433,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 885 "reflect.h2" +#line 887 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1449,7 +1451,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 926 "reflect.h2" +#line 928 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1474,7 +1476,7 @@ auto basic_enum( { std::string value = "-1"; -#line 949 "reflect.h2" +#line 951 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1513,7 +1515,7 @@ std::string value = "-1"; } // Compute the default underlying type, if it wasn't explicitly specified -#line 986 "reflect.h2" +#line 988 "reflect.h2" if (underlying_type.value() == "") { CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), @@ -1553,7 +1555,7 @@ std::string value = "-1"; } } -#line 1026 "reflect.h2" +#line 1028 "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' @@ -1592,7 +1594,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1062 "reflect.h2" +#line 1064 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1624,10 +1626,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1092 "reflect.h2" +#line 1094 "reflect.h2" } -#line 1104 "reflect.h2" +#line 1106 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1644,7 +1646,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1131 "reflect.h2" +#line 1133 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1666,7 +1668,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1177 "reflect.h2" +#line 1179 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1675,7 +1677,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1184 "reflect.h2" +#line 1186 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1700,7 +1702,7 @@ auto value = 0; } while (false); ++value; } } -#line 1207 "reflect.h2" +#line 1209 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1715,7 +1717,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1222 "reflect.h2" +#line 1224 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1724,12 +1726,12 @@ std::string storage = " _storage: std::aligned_storage_t t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1314 "reflect.h2" +#line 1316 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1919,7 +1921,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1414 "reflect.h2" +#line 1416 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index c55f4780a4..4bdab6a5b4 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -86,6 +86,8 @@ compiler_services: @polymorphic_base @copyable type = ) -> (ret: std::unique_ptr) = { + original_source := source; + generated_lines.push_back( std::vector() ); lines := generated_lines.back()&; @@ -127,7 +129,7 @@ compiler_services: @polymorphic_base @copyable type = generated_tokens* ); if !ret { - error( "parse failed - the source string is not a valid statement:\n(source)$"); + error( "parse failed - the source string is not a valid statement:\n(original_source)$"); } } From cb865b4ab2fdf4897fa8c6ed404d172fd3e38d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Sat, 16 Dec 2023 20:15:48 -0400 Subject: [PATCH 10/10] regenerate `reflect.h` --- source/reflect.h | 187 ++++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 93 deletions(-) diff --git a/source/reflect.h b/source/reflect.h index d8466c3f03..d1410315ff 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -27,19 +27,19 @@ class declaration; #line 326 "reflect.h2" class function_declaration; -#line 412 "reflect.h2" +#line 413 "reflect.h2" class object_declaration; -#line 448 "reflect.h2" +#line 449 "reflect.h2" class type_declaration; -#line 583 "reflect.h2" +#line 584 "reflect.h2" class alias_declaration; -#line 922 "reflect.h2" +#line 923 "reflect.h2" class value_member_info; -#line 1416 "reflect.h2" +#line 1438 "reflect.h2" } } @@ -348,7 +348,7 @@ class function_declaration public: [[nodiscard]] auto get_parameters() const& -> std::vector; -#line 383 "reflect.h2" +#line 384 "reflect.h2" public: [[nodiscard]] auto is_binary_comparison_function() const& -> bool; public: auto default_to_virtual() & -> void; @@ -359,103 +359,103 @@ class function_declaration public: function_declaration(function_declaration const& that); -#line 406 "reflect.h2" +#line 407 "reflect.h2" }; -#line 409 "reflect.h2" +#line 410 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 416 "reflect.h2" +#line 417 "reflect.h2" public: explicit object_declaration( declaration_node* n_, cpp2::in s ); -#line 426 "reflect.h2" +#line 427 "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 437 "reflect.h2" public: [[nodiscard]] auto initializer() const& -> std::string; public: object_declaration(object_declaration const& that); -#line 442 "reflect.h2" +#line 443 "reflect.h2" }; -#line 445 "reflect.h2" +#line 446 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 452 "reflect.h2" +#line 453 "reflect.h2" public: explicit type_declaration( declaration_node* n_, cpp2::in s ); -#line 462 "reflect.h2" +#line 463 "reflect.h2" public: auto reserve_names(cpp2::in name, auto&& ...etc) const& -> void; -#line 474 "reflect.h2" +#line 475 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const& -> bool; public: [[nodiscard]] auto is_final() const& -> bool; public: [[nodiscard]] auto make_final() & -> bool; public: [[nodiscard]] auto get_member_functions() const& -> std::vector; -#line 489 "reflect.h2" +#line 490 "reflect.h2" public: [[nodiscard]] auto get_member_functions_needing_initializer() const& -> std::vector; -#line 504 "reflect.h2" +#line 505 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const& -> std::vector; -#line 514 "reflect.h2" +#line 515 "reflect.h2" public: [[nodiscard]] auto get_member_types() const& -> std::vector; -#line 524 "reflect.h2" +#line 525 "reflect.h2" public: [[nodiscard]] auto get_member_aliases() const& -> std::vector; -#line 534 "reflect.h2" +#line 535 "reflect.h2" public: [[nodiscard]] auto get_members() const& -> std::vector; struct query_declared_value_set_functions_ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 544 "reflect.h2" +#line 545 "reflect.h2" public: [[nodiscard]] auto query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret; -#line 559 "reflect.h2" +#line 560 "reflect.h2" public: auto add_member(cpp2::in source) & -> void; -#line 573 "reflect.h2" +#line 574 "reflect.h2" public: auto remove_marked_members() & -> void; public: auto remove_all_members() & -> void; public: auto disable_member_function_generation() & -> void; public: type_declaration(type_declaration const& that); -#line 577 "reflect.h2" +#line 578 "reflect.h2" }; -#line 580 "reflect.h2" +#line 581 "reflect.h2" //----------------------------------------------------------------------- // Alias declarations // class alias_declaration : public declaration { -#line 587 "reflect.h2" +#line 588 "reflect.h2" public: explicit alias_declaration( declaration_node* n_, @@ -464,10 +464,10 @@ class alias_declaration public: alias_declaration(alias_declaration const& that); -#line 596 "reflect.h2" +#line 597 "reflect.h2" }; -#line 599 "reflect.h2" +#line 600 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -482,7 +482,7 @@ class alias_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 617 "reflect.h2" +#line 618 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -497,7 +497,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 656 "reflect.h2" +#line 657 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -519,7 +519,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 700 "reflect.h2" +#line 701 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -545,7 +545,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 744 "reflect.h2" +#line 745 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -553,19 +553,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 754 "reflect.h2" +#line 755 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 762 "reflect.h2" +#line 763 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 771 "reflect.h2" +#line 772 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -584,7 +584,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 808 "reflect.h2" +#line 809 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -594,7 +594,7 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 833 "reflect.h2" +#line 834 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." @@ -607,13 +607,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 849 "reflect.h2" +#line 850 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 855 "reflect.h2" +#line 856 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 862 "reflect.h2" +#line 863 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -641,7 +641,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 905 "reflect.h2" +#line 906 "reflect.h2" //----------------------------------------------------------------------- // // "C enumerations constitute a curiously half-baked concept. ... @@ -671,7 +671,7 @@ auto basic_enum( cpp2::in bitwise ) -> void; -#line 1097 "reflect.h2" +#line 1110 "reflect.h2" //----------------------------------------------------------------------- // // "An enum[...] is a totally ordered value type that stores a @@ -683,7 +683,7 @@ auto basic_enum( // auto cpp2_enum(meta::type_declaration& t) -> void; -#line 1123 "reflect.h2" +#line 1136 "reflect.h2" //----------------------------------------------------------------------- // // "flag_enum expresses an enumeration that stores values @@ -696,7 +696,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void; // auto flag_enum(meta::type_declaration& t) -> void; -#line 1155 "reflect.h2" +#line 1168 "reflect.h2" //----------------------------------------------------------------------- // // "As with void*, programmers should know that unions [...] are @@ -723,14 +723,14 @@ auto flag_enum(meta::type_declaration& t) -> void; auto cpp2_union(meta::type_declaration& t) -> void; -#line 1302 "reflect.h2" +#line 1324 "reflect.h2" //----------------------------------------------------------------------- // // print - output a pretty-printed visualization of t // auto print(cpp2::in t) -> void; -#line 1312 "reflect.h2" +#line 1334 "reflect.h2" //----------------------------------------------------------------------- // // apply_metafunctions @@ -741,7 +741,7 @@ auto print(cpp2::in t) -> void; auto const& error ) -> bool; -#line 1416 "reflect.h2" +#line 1438 "reflect.h2" } } @@ -1070,7 +1070,7 @@ declaration::declaration(declaration const& that) auto function_declaration::add_initializer(cpp2::in source) & -> void -#line 392 "reflect.h2" +#line 393 "reflect.h2" { (*this).expects(!(has_initializer()), "cannot add an initializer to a function that already has one"); (*this).expects(parent_is_type(), "cannot add an initializer to a function that isn't in a type scope"); @@ -1079,7 +1079,7 @@ declaration::declaration(declaration const& that) //require( parent_is_type(), // "cannot add an initializer to a function that isn't in a type scope"); -#line 398 "reflect.h2" +#line 399 "reflect.h2" auto stmt {parse_statement(source)}; if (!((cpp2::as_(stmt)))) { error("cannot add an initializer that is not a valid statement"); @@ -1092,14 +1092,14 @@ declaration::declaration(declaration const& that) function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} -#line 416 "reflect.h2" +#line 417 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 421 "reflect.h2" +#line 422 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); @@ -1125,14 +1125,14 @@ declaration::declaration(declaration const& that) object_declaration::object_declaration(object_declaration const& that) : declaration{ static_cast(that) }{} -#line 452 "reflect.h2" +#line 453 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 457 "reflect.h2" +#line 458 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); @@ -1222,13 +1222,13 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto type_declaration::query_declared_value_set_functions() const& -> query_declared_value_set_functions_ret -#line 551 "reflect.h2" +#line 552 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 552 "reflect.h2" +#line 553 "reflect.h2" auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::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); @@ -1258,14 +1258,14 @@ declaration::declaration(declaration const& that) type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} -#line 587 "reflect.h2" +#line 588 "reflect.h2" alias_declaration::alias_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 592 "reflect.h2" +#line 593 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); @@ -1274,13 +1274,13 @@ declaration::declaration(declaration const& that) alias_declaration::alias_declaration(alias_declaration const& that) : declaration{ static_cast(that) }{} -#line 611 "reflect.h2" +#line 612 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } -#line 629 "reflect.h2" +#line 630 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1307,7 +1307,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 675 "reflect.h2" +#line 676 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -1332,7 +1332,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 720 "reflect.h2" +#line 721 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1357,25 +1357,25 @@ auto ordered_impl( } } -#line 749 "reflect.h2" +#line 750 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 757 "reflect.h2" +#line 758 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 765 "reflect.h2" +#line 766 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 787 "reflect.h2" +#line 788 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1397,7 +1397,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 815 "reflect.h2" +#line 816 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { CPP2_UFCS(copyable)(t); @@ -1416,7 +1416,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 843 "reflect.h2" +#line 844 "reflect.h2" auto value(meta::type_declaration& t) -> void { CPP2_UFCS(ordered)(t); @@ -1435,7 +1435,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void CPP2_UFCS(basic_value)(t); } -#line 887 "reflect.h2" +#line 888 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS(get_members)(t) ) @@ -1453,7 +1453,7 @@ auto cpp2_struct(meta::type_declaration& t) -> void CPP2_UFCS(disable_member_function_generation)(t); } -#line 928 "reflect.h2" +#line 929 "reflect.h2" auto basic_enum( meta::type_declaration& t, auto const& nextval, @@ -1478,7 +1478,7 @@ auto basic_enum( { std::string value = "-1"; -#line 951 "reflect.h2" +#line 952 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) if ( CPP2_UFCS(is_member_object)(m)) @@ -1516,6 +1516,7 @@ std::string value = "-1"; } } +#line 988 "reflect.h2" CPP2_UFCS(require)(t, !(CPP2_UFCS(empty)(enumerators)), "an enumeration must contain at least one enumerator value"); @@ -1559,7 +1560,7 @@ std::string value = "-1"; } } -#line 1028 "reflect.h2" +#line 1032 "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' @@ -1607,7 +1608,7 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; // Provide a 'to_string' function to print enumerator name(s) -#line 1064 "reflect.h2" +#line 1077 "reflect.h2" { if (bitwise) { to_string += " _ret : std::string = \"(\";\n"; @@ -1639,10 +1640,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; CPP2_UFCS(add_member)(t, std::move(to_string)); } } -#line 1094 "reflect.h2" +#line 1107 "reflect.h2" } -#line 1106 "reflect.h2" +#line 1119 "reflect.h2" auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator @@ -1659,7 +1660,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void ); } -#line 1133 "reflect.h2" +#line 1146 "reflect.h2" auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator @@ -1681,7 +1682,7 @@ auto flag_enum(meta::type_declaration& t) -> void ); } -#line 1179 "reflect.h2" +#line 1192 "reflect.h2" auto cpp2_union(meta::type_declaration& t) -> void { std::vector alternatives {}; @@ -1690,7 +1691,7 @@ auto value = 0; // 1. Gather: All the user-written members, and find/compute the max size -#line 1186 "reflect.h2" +#line 1199 "reflect.h2" for ( auto const& m : CPP2_UFCS(get_members)(t) ) { do @@ -1715,7 +1716,7 @@ auto value = 0; } while (false); ++value; } } -#line 1209 "reflect.h2" +#line 1222 "reflect.h2" std::string discriminator_type {}; if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; @@ -1730,7 +1731,7 @@ auto value = 0; discriminator_type = "i64"; }}} -#line 1224 "reflect.h2" +#line 1237 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents CPP2_UFCS(remove_marked_members)(t); @@ -1739,12 +1740,12 @@ std::string storage = " _storage: cpp2::aligned_storage t) -> void { std::cout << CPP2_UFCS(print)(t) << "\n"; } -#line 1316 "reflect.h2" +#line 1338 "reflect.h2" [[nodiscard]] auto apply_metafunctions( declaration_node& n, type_declaration& rtype, @@ -1947,7 +1948,7 @@ auto print(cpp2::in t) -> void return true; } -#line 1416 "reflect.h2" +#line 1438 "reflect.h2" } }