1 // Example program for matching summary functions and synthetic child providers. 2 // 3 // The classes here simulate code generated by a serialization tool like, for 4 // example, protocol buffers. But the actual "generated" class layout is 5 // extremely naive to simplify the example. 6 // 7 // The idea is that we want to have generic formatters for a bunch of message 8 // classes, because they are all generated following common patterns, but the 9 // matching can't be based in the type name, because it can be anything. 10 11 #include <string> 12 13 class Message { 14 // Dummy method definitions to illustrate a possible generic message API. 15 std::string serialize() { return "TODO"; } 16 Message* deserialize() { 17 return nullptr; // TODO. 18 } 19 }; 20 21 // This class could have been generated from a description like this. Assume 22 // fields are always optional, for simplicity (e.g. we don't care during 23 // serialization if a Customer has a name or not, we're just moving data around 24 // and validation happens elsewhere). 25 // 26 // message Customer { 27 // string name; 28 // int age; 29 // string address; 30 // } 31 class Customer : public Message { 32 private: 33 int _internal_bookkeeping_bits_; 34 35 // Presence bits. They are true if the field has been set. 36 bool _has_name_ = false; 37 bool _has_age_ = false; 38 bool _has_address_ = false; 39 40 // Actual field data. 41 std::string name_; 42 int age_; 43 std::string address_; 44 45 public: 46 // Getters and setters. 47 bool has_name() { return _has_name_; } 48 bool has_age() { return _has_age_; } 49 bool has_address() { return _has_address_; } 50 51 std::string name() { return name_; } 52 int age() { return age_; } 53 std::string address() { return address_; } 54 55 void set_name(std::string name) { 56 name_ = name; 57 _has_name_ = true; 58 } 59 void set_age(int age) { 60 age_ = age; 61 _has_age_ = true; 62 } 63 void set_address(std::string address) { 64 address_ = address; 65 _has_address_ = true; 66 } 67 }; 68 69 // message ProductOrder { 70 // string product_name; 71 // int amount; 72 // } 73 class ProductOrder : public Message { 74 private: 75 int _internal_bookkeeping_bits_; 76 77 // Presence bits. They are true if the field has been set. 78 bool _has_product_name_ = false; 79 bool _has_amount_ = false; 80 81 // Actual field data. 82 std::string product_name_; 83 int amount_; 84 85 public: 86 // Getters and setters. 87 bool has_product_name() { return _has_product_name_; } 88 bool has_amount() { return _has_amount_; } 89 90 std::string get_product_name() { return product_name_; } 91 int get_amount() { return amount_; } 92 93 void set_product_name(std::string product_name) { 94 product_name_ = product_name; 95 _has_product_name_ = true; 96 } 97 void set_amount(int amount) { 98 amount_ = amount; 99 _has_amount_ = true; 100 } 101 }; 102 103 int main(int argc, char **argv) { 104 Customer customer; 105 customer.set_name("C. Ustomer"); 106 customer.set_address("123 Fake St."); 107 // no age, so we can check absent fields get omitted. 108 109 ProductOrder order; 110 order.set_product_name("widget"); 111 order.set_amount(100); 112 return 0; // break here. 113 } 114 115