| // Example program for matching summary functions and synthetic child providers. |
| // |
| // The classes here simulate code generated by a serialization tool like, for |
| // example, protocol buffers. But the actual "generated" class layout is |
| // extremely naive to simplify the example. |
| // |
| // The idea is that we want to have generic formatters for a bunch of message |
| // classes, because they are all generated following common patterns, but the |
| // matching can't be based in the type name, because it can be anything. |
| |
| #include <string> |
| |
| class Message { |
| // Dummy method definitions to illustrate a possible generic message API. |
| std::string serialize() { return "TODO"; } |
| Message* deserialize() { |
| return nullptr; // TODO. |
| } |
| }; |
| |
| // This class could have been generated from a description like this. Assume |
| // fields are always optional, for simplicity (e.g. we don't care during |
| // serialization if a Customer has a name or not, we're just moving data around |
| // and validation happens elsewhere). |
| // |
| // message Customer { |
| // string name; |
| // int age; |
| // string address; |
| // } |
| class Customer : public Message { |
| private: |
| int _internal_bookkeeping_bits_; |
| |
| // Presence bits. They are true if the field has been set. |
| bool _has_name_ = false; |
| bool _has_age_ = false; |
| bool _has_address_ = false; |
| |
| // Actual field data. |
| std::string name_; |
| int age_; |
| std::string address_; |
| |
| public: |
| // Getters and setters. |
| bool has_name() { return _has_name_; } |
| bool has_age() { return _has_age_; } |
| bool has_address() { return _has_address_; } |
| |
| std::string name() { return name_; } |
| int age() { return age_; } |
| std::string address() { return address_; } |
| |
| void set_name(std::string name) { |
| name_ = name; |
| _has_name_ = true; |
| } |
| void set_age(int age) { |
| age_ = age; |
| _has_age_ = true; |
| } |
| void set_address(std::string address) { |
| address_ = address; |
| _has_address_ = true; |
| } |
| }; |
| |
| // message ProductOrder { |
| // string product_name; |
| // int amount; |
| // } |
| class ProductOrder : public Message { |
| private: |
| int _internal_bookkeeping_bits_; |
| |
| // Presence bits. They are true if the field has been set. |
| bool _has_product_name_ = false; |
| bool _has_amount_ = false; |
| |
| // Actual field data. |
| std::string product_name_; |
| int amount_; |
| |
| public: |
| // Getters and setters. |
| bool has_product_name() { return _has_product_name_; } |
| bool has_amount() { return _has_amount_; } |
| |
| std::string get_product_name() { return product_name_; } |
| int get_amount() { return amount_; } |
| |
| void set_product_name(std::string product_name) { |
| product_name_ = product_name; |
| _has_product_name_ = true; |
| } |
| void set_amount(int amount) { |
| amount_ = amount; |
| _has_amount_ = true; |
| } |
| }; |
| |
| int main(int argc, char **argv) { |
| Customer customer; |
| customer.set_name("C. Ustomer"); |
| customer.set_address("123 Fake St."); |
| // no age, so we can check absent fields get omitted. |
| |
| ProductOrder order; |
| order.set_product_name("widget"); |
| order.set_amount(100); |
| return 0; // break here. |
| } |
| |