@@ -36,10 +36,10 @@ class type_declaration;
36
36
#line 589 "reflect.h2"
37
37
class alias_declaration ;
38
38
39
- #line 928 "reflect.h2"
39
+ #line 962 "reflect.h2"
40
40
class value_member_info ;
41
41
42
- #line 1445 "reflect.h2"
42
+ #line 1482 "reflect.h2"
43
43
}
44
44
45
45
}
@@ -621,6 +621,31 @@ auto partially_ordered_value(meta::type_declaration& t) -> void;
621
621
#line 868 "reflect.h2"
622
622
// -----------------------------------------------------------------------
623
623
//
624
+ // C.20: If you can avoid defining default operations, do
625
+ //
626
+ // ##### Reason
627
+ //
628
+ // It's the simplest and gives the cleanest semantics.
629
+ //
630
+ // ...
631
+ //
632
+ // This is known as "the rule of zero".
633
+ //
634
+ // -- C++ Core Guidelines
635
+ // C.20: If you can avoid defining any default operations, do
636
+ // <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-zero>
637
+ //
638
+ // -----------------------------------------------------------------------
639
+ //
640
+ // rule_of_zero
641
+ //
642
+ // a type without declared copy/move/destructor functions
643
+ //
644
+ auto rule_of_zero (meta::type_declaration& t) -> void;
645
+
646
+ #line 902 "reflect.h2"
647
+ // -----------------------------------------------------------------------
648
+ //
624
649
// "By definition, a `struct` is a `class` in which members
625
650
// are by default `public`; that is,
626
651
//
@@ -646,7 +671,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void;
646
671
//
647
672
auto cpp2_struct (meta::type_declaration& t) -> void;
648
673
649
- #line 911 "reflect.h2"
674
+ #line 945 "reflect.h2"
650
675
// -----------------------------------------------------------------------
651
676
//
652
677
// "C enumerations constitute a curiously half-baked concept. ...
@@ -676,7 +701,7 @@ auto basic_enum(
676
701
cpp2::in<bool > bitwise
677
702
) -> void;
678
703
679
- #line 1117 "reflect.h2"
704
+ #line 1151 "reflect.h2"
680
705
// -----------------------------------------------------------------------
681
706
//
682
707
// "An enum[...] is a totally ordered value type that stores a
@@ -688,7 +713,7 @@ auto basic_enum(
688
713
//
689
714
auto cpp2_enum (meta::type_declaration& t) -> void;
690
715
691
- #line 1143 "reflect.h2"
716
+ #line 1177 "reflect.h2"
692
717
// -----------------------------------------------------------------------
693
718
//
694
719
// "flag_enum expresses an enumeration that stores values
@@ -701,7 +726,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void;
701
726
//
702
727
auto flag_enum (meta::type_declaration& t) -> void;
703
728
704
- #line 1175 "reflect.h2"
729
+ #line 1209 "reflect.h2"
705
730
// -----------------------------------------------------------------------
706
731
//
707
732
// "As with void*, programmers should know that unions [...] are
@@ -728,14 +753,14 @@ auto flag_enum(meta::type_declaration& t) -> void;
728
753
729
754
auto cpp2_union (meta::type_declaration& t) -> void;
730
755
731
- #line 1331 "reflect.h2"
756
+ #line 1365 "reflect.h2"
732
757
// -----------------------------------------------------------------------
733
758
//
734
759
// print - output a pretty-printed visualization of t
735
760
//
736
761
auto print (cpp2::in<meta::type_declaration> t) -> void;
737
762
738
- #line 1341 "reflect.h2"
763
+ #line 1375 "reflect.h2"
739
764
// -----------------------------------------------------------------------
740
765
//
741
766
// apply_metafunctions
@@ -746,7 +771,7 @@ auto print(cpp2::in<meta::type_declaration> t) -> void;
746
771
auto const & error
747
772
) -> bool;
748
773
749
- #line 1445 "reflect.h2"
774
+ #line 1482 "reflect.h2"
750
775
}
751
776
752
777
}
@@ -1081,7 +1106,7 @@ declaration::declaration(declaration const& that)
1081
1106
{
1082
1107
if ((*this ).has_handler () && !(!(has_initializer ())) ) { (*this ).report_violation (CPP2_CONTRACT_MSG (" cannot add an initializer to a function that already has one" )); }
1083
1108
if ((*this ).has_handler () && !(parent_is_type ()) ) { (*this ).report_violation (CPP2_CONTRACT_MSG (" cannot add an initializer to a function that isn't in a type scope" )); }
1084
- // require( !has_initializer(),
1109
+ // require( !has_initializer(),
1085
1110
// "cannot add an initializer to a function that already has one");
1086
1111
// require( parent_is_type(),
1087
1112
// "cannot add an initializer to a function that isn't in a type scope");
@@ -1442,7 +1467,20 @@ auto partially_ordered_value(meta::type_declaration& t) -> void
1442
1467
CPP2_UFCS (basic_value)(t);
1443
1468
}
1444
1469
1445
- #line 893 "reflect.h2"
1470
+ #line 890 "reflect.h2"
1471
+ auto rule_of_zero (meta::type_declaration& t) -> void
1472
+ {
1473
+ for ( auto & mf : CPP2_UFCS (get_member_functions)(t) )
1474
+ {
1475
+ CPP2_UFCS (require)(t, !(CPP2_UFCS (is_constructor_with_that)(mf))
1476
+ && !(CPP2_UFCS (is_assignment_with_that)(mf))
1477
+ && !(CPP2_UFCS (is_destructor)(mf)),
1478
+ " the rule of zero requires no copy/move/destructor functions" );
1479
+ }
1480
+ CPP2_UFCS (disable_member_function_generation)(t);
1481
+ }
1482
+
1483
+ #line 927 "reflect.h2"
1446
1484
auto cpp2_struct (meta::type_declaration& t) -> void
1447
1485
{
1448
1486
for ( auto & m : CPP2_UFCS (get_members)(t) )
@@ -1457,10 +1495,10 @@ auto cpp2_struct(meta::type_declaration& t) -> void
1457
1495
" a struct may not have a user-defined operator=" );
1458
1496
}
1459
1497
}
1460
- CPP2_UFCS (disable_member_function_generation )(t);
1498
+ CPP2_UFCS (rule_of_zero )(t);
1461
1499
}
1462
1500
1463
- #line 934 "reflect.h2"
1501
+ #line 968 "reflect.h2"
1464
1502
auto basic_enum (
1465
1503
meta::type_declaration& t,
1466
1504
auto const & nextval,
@@ -1485,7 +1523,7 @@ auto basic_enum(
1485
1523
{
1486
1524
std::string value{" -1" };
1487
1525
1488
- #line 957 "reflect.h2"
1526
+ #line 991 "reflect.h2"
1489
1527
for (
1490
1528
auto const & m : CPP2_UFCS (get_members)(t) )
1491
1529
if ( CPP2_UFCS (is_member_object)(m))
@@ -1523,7 +1561,7 @@ std::string value{"-1"};
1523
1561
}
1524
1562
}
1525
1563
1526
- #line 993 "reflect.h2"
1564
+ #line 1027 "reflect.h2"
1527
1565
if ((CPP2_UFCS (empty)(enumerators))) {
1528
1566
CPP2_UFCS (error)(t, " an enumeration must contain at least one enumerator value" );
1529
1567
return ;
@@ -1569,7 +1607,7 @@ std::string value{"-1"};
1569
1607
}
1570
1608
}
1571
1609
1572
- #line 1039 "reflect.h2"
1610
+ #line 1073 "reflect.h2"
1573
1611
// 2. Replace: Erase the contents and replace with modified contents
1574
1612
//
1575
1613
// Note that most values and functions are declared as '==' compile-time values, i.e. Cpp1 'constexpr'
@@ -1617,7 +1655,7 @@ std::string to_string{" to_string: (this) -> std::string = { \n"};
1617
1655
1618
1656
// Provide a 'to_string' function to print enumerator name(s)
1619
1657
1620
- #line 1084 "reflect.h2"
1658
+ #line 1118 "reflect.h2"
1621
1659
{
1622
1660
if (bitwise) {
1623
1661
to_string += " _ret : std::string = \" (\" ;\n " ;
@@ -1649,10 +1687,10 @@ std::string to_string{" to_string: (this) -> std::string = { \n"};
1649
1687
CPP2_UFCS (add_member)(t, std::move (to_string));
1650
1688
}
1651
1689
}
1652
- #line 1114 "reflect.h2"
1690
+ #line 1148 "reflect.h2"
1653
1691
}
1654
1692
1655
- #line 1126 "reflect.h2"
1693
+ #line 1160 "reflect.h2"
1656
1694
auto cpp2_enum (meta::type_declaration& t) -> void
1657
1695
{
1658
1696
// Let basic_enum do its thing, with an incrementing value generator
@@ -1669,7 +1707,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void
1669
1707
);
1670
1708
}
1671
1709
1672
- #line 1153 "reflect.h2"
1710
+ #line 1187 "reflect.h2"
1673
1711
auto flag_enum (meta::type_declaration& t) -> void
1674
1712
{
1675
1713
// Let basic_enum do its thing, with a power-of-two value generator
@@ -1691,7 +1729,7 @@ auto flag_enum(meta::type_declaration& t) -> void
1691
1729
);
1692
1730
}
1693
1731
1694
- #line 1199 "reflect.h2"
1732
+ #line 1233 "reflect.h2"
1695
1733
auto cpp2_union (meta::type_declaration& t) -> void
1696
1734
{
1697
1735
std::vector<value_member_info> alternatives {};
@@ -1700,7 +1738,7 @@ auto value{0};
1700
1738
1701
1739
// 1. Gather: All the user-written members, and find/compute the max size
1702
1740
1703
- #line 1206 "reflect.h2"
1741
+ #line 1240 "reflect.h2"
1704
1742
for (
1705
1743
1706
1744
auto const & m : CPP2_UFCS (get_members)(t) ) { do
@@ -1725,7 +1763,7 @@ auto value{0};
1725
1763
} while (false ); ++value; }
1726
1764
}
1727
1765
1728
- #line 1229 "reflect.h2"
1766
+ #line 1263 "reflect.h2"
1729
1767
std::string discriminator_type {};
1730
1768
if (cpp2::cmp_less (CPP2_UFCS (ssize)(alternatives),std::numeric_limits<cpp2::i8>::max ())) {
1731
1769
discriminator_type = " i8" ;
@@ -1740,7 +1778,7 @@ auto value{0};
1740
1778
discriminator_type = " i64" ;
1741
1779
}}}
1742
1780
1743
- #line 1244 "reflect.h2"
1781
+ #line 1278 "reflect.h2"
1744
1782
// 2. Replace: Erase the contents and replace with modified contents
1745
1783
1746
1784
CPP2_UFCS (remove_marked_members)(t);
@@ -1749,40 +1787,40 @@ std::string storage{" _storage: cpp2::aligned_storage<cpp2::max( "};
1749
1787
1750
1788
// Provide storage
1751
1789
1752
- #line 1250 "reflect.h2"
1790
+ #line 1284 "reflect.h2"
1753
1791
{
1754
1792
{
1755
1793
std::string comma{" " };
1756
1794
1757
- #line 1252 "reflect.h2"
1795
+ #line 1286 "reflect.h2"
1758
1796
for (
1759
1797
1760
1798
auto const & e : alternatives ) { do {
1761
1799
storage += comma + (" sizeof(" + cpp2::to_string (e.type ) + " )" );
1762
1800
} while (false ); comma = " , " ; }
1763
1801
}
1764
1802
1765
- #line 1258 "reflect.h2"
1803
+ #line 1292 "reflect.h2"
1766
1804
storage += " ), cpp2::max( " ;
1767
1805
{
1768
1806
std::string comma{" " };
1769
1807
1770
- #line 1261 "reflect.h2"
1808
+ #line 1295 "reflect.h2"
1771
1809
for (
1772
1810
1773
1811
auto const & e : alternatives ) { do {
1774
1812
storage += comma + (" alignof(" + cpp2::to_string (e.type ) + " )" );
1775
1813
} while (false ); comma = " , " ; }
1776
1814
}
1777
1815
1778
- #line 1267 "reflect.h2"
1816
+ #line 1301 "reflect.h2"
1779
1817
storage += " )> = ();\n " ;
1780
1818
CPP2_UFCS (add_member)(t, std::move (storage));
1781
1819
}
1782
1820
}
1783
1821
1784
1822
// Provide discriminator
1785
- #line 1272 "reflect.h2"
1823
+ #line 1306 "reflect.h2"
1786
1824
CPP2_UFCS (add_member)(t, (" _discriminator: " + cpp2::to_string (std::move (discriminator_type)) + " = -1;\n " ));
1787
1825
1788
1826
// Add the alternatives: is_alternative, get_alternative, and set_alternative
@@ -1804,7 +1842,7 @@ std::string destroy{" private _destroy: (inout this) = {\n"};
1804
1842
1805
1843
// Add destroy
1806
1844
1807
- #line 1291 "reflect.h2"
1845
+ #line 1325 "reflect.h2"
1808
1846
{
1809
1847
for (
1810
1848
auto const & a : alternatives ) {
@@ -1818,7 +1856,7 @@ std::string destroy{" private _destroy: (inout this) = {\n"};
1818
1856
}
1819
1857
1820
1858
// Add the destructor
1821
- #line 1303 "reflect.h2"
1859
+ #line 1337 "reflect.h2"
1822
1860
CPP2_UFCS (add_member)(t, " operator=: (move this) = { _destroy(); }" );
1823
1861
1824
1862
// Add default constructor
@@ -1828,7 +1866,7 @@ std::string value_set{""};
1828
1866
1829
1867
// Add copy/move construction and assignment
1830
1868
1831
- #line 1310 "reflect.h2"
1869
+ #line 1344 "reflect.h2"
1832
1870
{
1833
1871
for (
1834
1872
auto const & a : alternatives ) {
@@ -1848,16 +1886,16 @@ std::string value_set{""};
1848
1886
);
1849
1887
}
1850
1888
}
1851
- #line 1328 "reflect.h2"
1889
+ #line 1362 "reflect.h2"
1852
1890
}
1853
1891
1854
- #line 1335 "reflect.h2"
1892
+ #line 1369 "reflect.h2"
1855
1893
auto print (cpp2::in<meta::type_declaration> t) -> void
1856
1894
{
1857
1895
std::cout << CPP2_UFCS (print)(t) << " \n " ;
1858
1896
}
1859
1897
1860
- #line 1345 "reflect.h2"
1898
+ #line 1379 "reflect.h2"
1861
1899
[[nodiscard]] auto apply_metafunctions (
1862
1900
declaration_node& n,
1863
1901
type_declaration& rtype,
@@ -1923,6 +1961,9 @@ auto print(cpp2::in<meta::type_declaration> t) -> void
1923
1961
else {if (name == " partially_ordered_value" ) {
1924
1962
partially_ordered_value (rtype);
1925
1963
}
1964
+ else {if (name == " rule_of_zero" ) {
1965
+ rule_of_zero (rtype);
1966
+ }
1926
1967
else {if (name == " struct" ) {
1927
1968
cpp2_struct (rtype);
1928
1969
}
@@ -1940,9 +1981,9 @@ auto print(cpp2::in<meta::type_declaration> t) -> void
1940
1981
}
1941
1982
else {
1942
1983
error (" unrecognized metafunction name: " + name);
1943
- error (" (temporary alpha limitation) currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, copyable, basic_value, value, weakly_ordered_value, partially_ordered_value, struct, enum, flag_enum, union, print" );
1984
+ error (" (temporary alpha limitation) currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, copyable, basic_value, value, weakly_ordered_value, partially_ordered_value, rule_of_zero, struct, enum, flag_enum, union, print" );
1944
1985
return false ;
1945
- }}}}}}}}}}}}}}}
1986
+ }}}}}}}}}}}}}}}}
1946
1987
1947
1988
if ((
1948
1989
!(CPP2_UFCS (empty)(args))
@@ -1957,7 +1998,7 @@ auto print(cpp2::in<meta::type_declaration> t) -> void
1957
1998
return true ;
1958
1999
}
1959
2000
1960
- #line 1445 "reflect.h2"
2001
+ #line 1482 "reflect.h2"
1961
2002
}
1962
2003
1963
2004
}
0 commit comments