### Bootstrap vcpkg Source: https://rfl.getml.com/install Initializes the vcpkg package manager, which is necessary for installing reflect-cpp and its dependencies. ```bash git submodule update --init ./vcpkg/bootstrap-vcpkg.sh # Linux, macOS ./vcpkg/bootstrap-vcpkg.bat # Windows ``` -------------------------------- ### Install reflect-cpp using Conan Source: https://rfl.getml.com/install Installs the Conan package manager and detects the current profile, preparing for the installation of reflect-cpp. ```bash pipx install conan conan profile detect ``` -------------------------------- ### Install reflect-cpp using vcpkg Source: https://rfl.getml.com/install Installs the reflect-cpp library using the vcpkg package manager. This is the primary method for incorporating reflect-cpp into your project. ```bash vcpkg install reflectcpp ``` ```bash vcpkg add port reflectcpp ``` -------------------------------- ### Relative Include Example (C++) Source: https://rfl.getml.com/contributing Demonstrates the preferred way to include internal headers in the rfl_getml project, emphasizing relative paths for better maintainability and portability. ```c++ #include "to_ptr_named_tuple.hpp" ``` -------------------------------- ### Troubleshoot vcpkg build issues Source: https://rfl.getml.com/install Provides commands to resolve common problems encountered during vcpkg builds, such as cleaning build directories or setting environment variables for specific architectures. ```bash rm -rf build export VCPKG_FORCE_SYSTEM_BINARIES=arm export VCPKG_FORCE_SYSTEM_BINARIES=1 cmake -S . -B build ... -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ cmake -S . -B build ... -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 ``` -------------------------------- ### Build reflect-cpp with Conan (JSON only) Source: https://rfl.getml.com/install Builds the JSON-only version of reflect-cpp using Conan. This command ensures the correct C++ standard is used and resolves any missing build dependencies. ```bash conan build . --build=missing -s compiler.cppstd=gnu20 ``` -------------------------------- ### Compile reflect-cpp with CMake (JSON only) Source: https://rfl.getml.com/install Compiles the reflect-cpp library with support for JSON serialization using CMake. This method allows direct integration into your build system. ```bash cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release cmake --build build -j 4 # gcc, clang cmake --build build --config Release -j 4 # MSVC ``` -------------------------------- ### Compile reflect-cpp with CMake (all formats) Source: https://rfl.getml.com/install Compiles the reflect-cpp library with support for multiple serialization formats using CMake. This command enables various optional features for different data formats. ```bash cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_AVRO=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_CAPNPROTO=ON -DREFLECTCPP_CBOR=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_MSGPACK=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_TOML=ON -DREFLECTCPP_UBJSON=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release cmake --build build -j 4 # gcc, clang cmake --build build --config Release -j 4 # MSVC ``` -------------------------------- ### Build reflect-cpp with Conan (all formats) Source: https://rfl.getml.com/install Builds reflect-cpp with support for multiple serialization formats using Conan. This command enables various optional features for different data formats during the build process. ```bash conan build . --build=missing -s compiler.cppstd=gnu20 -o *:with_cbor=True -o *:with_flatbuffers=True -o *:with_msgpack=True -o *:with_toml=True -o *:with_ubjson=True -o *:with_xml=True -o *:with_yaml=True ``` -------------------------------- ### Example JSON Schema Output Source: https://rfl.getml.com/json_schema An example of a JSON schema generated from a C++ struct, detailing the structure, types, and constraints for validation and code generation. ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "#/definitions/Person", "definitions": { "Person": { "type": "object", "properties": { "children": { "type": "array", "items": { "$ref": "#/definitions/Person" } }, "email": { "type": "string", "pattern": "^[a-zA-Z0-9._%+\\-\\]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$" }, "first_name": { "type": "string" }, "last_name": { "type": "string" }, "salary": { "type": "number" } }, "required": [ "children", "email", "first_name", "last_name", "salary" ] } } } ``` -------------------------------- ### Integrate reflect-cpp into a CMake project Source: https://rfl.getml.com/install Adds reflect-cpp as a subdirectory to your CMake project and links against the library. This allows seamless integration of reflect-cpp's functionality into your application. ```cmake add_subdirectory(reflect-cpp) # Add this project as a subdirectory set(REFLECTCPP_AVRO ON) # Optional set(REFLECTCPP_BSON ON) # Optional set(REFLECTCPP_CBOR ON) # Optional set(REFLECTCPP_FLEXBUFFERS ON) # Optional set(REFLECTCPP_MSGPACK ON) # Optional set(REFLECTCPP_TOML ON) # Optional set(REFLECTCPP_UBJSON ON) # Optional set(REFLECTCPP_XML ON) # Optional set(REFLECTCPP_YAML ON) # Optional target_link_libraries(your_project PRIVATE reflectcpp) # Link against the library ``` -------------------------------- ### Parquet Compression Settings Examples Source: https://rfl.getml.com/supported_formats/parquet Demonstrates how to configure different compression algorithms for Parquet files using the rfl::parquet::Settings struct, including SNAPPY, GZIP, ZSTD, and UNCOMPRESSED. ```cpp // Examples of different compression settings const auto snappy_settings = rfl::parquet::Settings{}.with_compression(rfl::parquet::Compression::SNAPPY); const auto gzip_settings = rfl::parquet::Settings{}.with_compression(rfl::parquet::Compression::GZIP); const auto zstd_settings = rfl::parquet::Settings{}.with_compression(rfl::parquet::Compression::ZSTD); const auto uncompressed_settings = rfl::parquet::Settings{}.with_compression(rfl::parquet::Compression::UNCOMPRESSED); ``` -------------------------------- ### rfl::Literal Example with Struct and JSON Parsing Source: https://rfl.getml.com/literals An example demonstrating the use of rfl::Literal for struct members and how it integrates with JSON parsing. It highlights compile-time checks and potential runtime errors if JSON data doesn't match literal constraints. ```cpp // There are only five Simpsons. using FirstName = rfl::Literal<"Homer", "Marge", "Bart", "Lisa", "Maggie"> ; // All Simpsons have the last name. using LastName = rfl::Literal<"Simpson"> ; struct Person { rfl::Rename<"firstName", FirstName> first_name; rfl::Rename<"lastName", LastName> last_name; std::vector children; }; // Leads to a runtime error, if the field "lastName" is not "Simpson" // and the field "firstName" is not "Homer", "Marge", "Bart", "Lisa" or "Maggie". const auto simpson_family_member = rfl::json::read(some_json_string).value(); ``` -------------------------------- ### BSON Serialization Setup Source: https://rfl.getml.com/supported_formats/bson To use BSON support, include the BSON header and link the libbson library. When compiling reflect-cpp, ensure the BSON feature is enabled via CMake. For vcpkg users, a feature flag should handle this. ```c++ #include // Link against libbson and compile with -DREFLECTCPP_BSON=ON ``` -------------------------------- ### Initial JSON String Example Source: https://rfl.getml.com/optional_fields This is an example JSON string generated from a struct where all fields are considered required. If any of these fields were missing during deserialization, it would result in a runtime error. ```json {"firstName":"Bart","lastName":"Simpson","children":[]} ``` -------------------------------- ### Dynamically Building Structs with rfl::from_generic Source: https://rfl.getml.com/generic Provides a practical example of using `rfl::from_generic` to construct a C++ struct (`Person`) from a dynamically created `rfl::Generic::Object`. ```cpp struct Person { std::string first_name; std::string last_name; int age; }; auto bart = rfl::Generic::Object(); bart["first_name"] = "Bart"; bart["last_name"] = "Simpson"; bart["age"] = 10; const auto person = rfl::from_generic(bart).value(); ``` -------------------------------- ### Using rfl::Binary, rfl::Hex, rfl::Oct for Number Representation Source: https://rfl.getml.com/number_systems Demonstrates the usage of rfl::Binary, rfl::Hex, and rfl::Oct to represent numbers in binary, hexadecimal, and octal formats within a C++ struct. It shows how to initialize these types and provides an example of the resulting JSON output. ```C++ struct ExampleStruct { rfl::Binary binary; rfl::Hex hex; rfl::Oct oct; }; const auto example = ExampleStruct{ .binary = 30, .hex = 30, .oct = 30}; // Resulting JSON: // {"binary":"00011110","hex":"1e","oct":"36"} ``` -------------------------------- ### Load CSV Data from File Source: https://rfl.getml.com/supported_formats/csv Provides an example of loading CSV data directly from a file path into a specified collection type. Error handling is managed via the `rfl::Result` type. ```cpp const rfl::Result> result = rfl::csv::load>("/path/to/file.csv"); ``` -------------------------------- ### rfl::Reflector with Custom Type Serialization Source: https://rfl.getml.com/custom_parser This C++ example illustrates how to specialize `rfl::Reflector` for a custom type `MyCustomType` that serializes to a `std::string`. It defines `ReflType` as `std::string` and implements `to` and `from` methods using `MyCustomType::from_string` and `MyCustomType::to_string` respectively. ```cpp namespace rfl { template <> struct Reflector { using ReflType = std::string; static MyCustomType to(const ReflType& str) noexcept { return MyCustomType::from_string(str); } static ReflType from(const MyCustomType& v) { return v.to_string(); } }; } ``` -------------------------------- ### Flatten structs with rfl::Flatten in C++ Source: https://rfl.getml.com/flatten_structs This example shows how to use rfl::Flatten to include all fields from a 'Person' struct into an 'Employee' struct. The fields are then serialized into a single JSON object. This approach simulates inheritance through composition. ```C++ struct Person { std::string first_name; std::string last_name; int age; }; struct Employee { rfl::Flatten person; std::string employer; float salary; }; const auto employee = Employee{ .person = Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}, .employer = "Mr. Burns", .salary = 60000.0}; const auto json_str = rfl::json::write(employee); ``` -------------------------------- ### Accessing and Assigning Skipped Fields Source: https://rfl.getml.com/rfl_skip Provides examples of how to access the underlying value of a field marked with rfl::Skip or its variants using member functions like 'town()', 'town.get()', or 'town.value()'. It also demonstrates assigning a new value to such a field. ```C++ person.town(); person.town.get(); person.town.value(); person.town = "Springfield"; ``` -------------------------------- ### Allowing Raw Pointers with rfl::AllowRawPtrs in C++ Source: https://rfl.getml.com/concepts/processors Illustrates how to use the rfl::AllowRawPtrs processor to enable reading into raw pointers, std::string_view, or std::span. It highlights the user's responsibility for memory management to prevent leaks and provides examples of manual cleanup. ```C++ struct Person { rfl::Rename<"firstName", std::string> first_name; rfl::Rename<"lastName", std::string> last_name = "Simpson"; std::vector* children; }; const auto person = rfl::json::read(json_str); ``` ```C++ void delete_raw_pointers(const Person& _person) { if (!_person.children) { return; } for (const auto& child: _person.children) { delete_raw_pointers(child); } delete _person.children; } delete_raw_pointers(person); ``` ```C++ delete[] person.string_view.data(); if(!person.span.empty()) { delete[] person.span.data(); } ``` -------------------------------- ### Handle rfl::TaggedUnion with Visitor Pattern in C++ Source: https://rfl.getml.com/variants_and_tagged_unions This snippet demonstrates using the visitor pattern with rfl::TaggedUnion in C++. It defines a tagged union of shapes and a visitor function that identifies the type of the shape and prints its dimensions. The example shows how to retrieve the underlying variant using `.variant()` and apply the visitor using rfl::visit or the tagged union's visit method. A static assert ensures exhaustive type handling. ```cpp using Shapes = rfl::TaggedUnion<"shape", Circle, Square, Rectangle>; const Shapes my_shape = Rectangle{.height = 10, .width = 5}; const auto handle_shapes = [](const auto& s) { using Type = std::decay_t; if constexpr (std::is_same()) { std::cout << is circle, radius: << s.radius() << std::endl; } else if constexpr (std::is_same()) { std::cout << is rectangle, width: << s.width() << ", height: " << s.height() << std::endl; } else if constexpr (std::is_same()) { std::cout << is square, width: << s.width() << std::endl; } else { static_assert(rfl::always_false_v, "Not all cases were covered."); } }; rfl::visit(handle_shapes, my_shape); // OK my_shape.visit(handle_shapes); // also OK ``` -------------------------------- ### Flatten structs using rfl::Field syntax in C++ Source: https://rfl.getml.com/flatten_structs This example demonstrates flattening structs using the rfl::Field syntax, allowing custom field names in the output JSON. It shows how 'Person' fields are flattened into 'Employee', producing a JSON object with specified field names. ```C++ struct Person { rfl::Field<"firstName", std::string> first_name; rfl::Field<"lastName", std::string> last_name; rfl::Field<"age", int> age; }; struct Employee { rfl::Flatten person; rfl::Field<"salary", float> salary; }; const auto employee = Employee{ .person = Person{.first_name = "Homer", .last_name = "Simpson", .age = 45}, .salary = 60000.0 }; const auto json_str = rfl::json::write(employee); ``` -------------------------------- ### Bootstrap vcpkg (Shell) Source: https://rfl.getml.com/contributing Provides commands to initialize and bootstrap vcpkg, the dependency manager used by reflect-cpp, ensuring necessary libraries like gtest are available for testing. ```shell git submodule update --init ./vcpkg/bootstrap-vcpkg.sh # Linux, macOS ./vcpkg/bootstrap-vcpkg.bat # Windows # You may be prompted to install additional dependencies. ``` -------------------------------- ### Valid C++ Enumeration Definitions for reflect-cpp Source: https://rfl.getml.com/enums Provides examples of valid C++ enumeration definitions that are supported by reflect-cpp, including scoped and unscoped enumerations. It also shows an example of an unsupported anonymous enumeration. ```C++ // OK - scoped enumeration enum class Color1 { red, green, blue, yellow }; // OK - scoped enumeration enum struct Color2 { red, green, blue, yellow }; // OK - unscoped enumeration enum Color3 { red, green, blue, yellow }; /// Unsupported: Anonymous enumeration enum { red, green, blue, yellow }; ``` -------------------------------- ### Initialize C++ Struct Source: https://rfl.getml.com/concepts/structs Demonstrates the initialization of a C++ struct instance. It shows how to assign values to members directly during object creation, including initializing a vector. ```cpp const auto bart = Person{.first_name = "Bart", .last_name = "Simpson", .children = std::vector()}; ``` -------------------------------- ### Save Person to UBJSON file Source: https://rfl.getml.com/supported_formats/ubjson Provides an example of saving a C++ 'Person' object to a UBJSON file using reflect-cpp's UBJSON save function. ```cpp const auto person = Person{...}; rfl::ubjson::save("/path/to/file.ubjson", person); ``` -------------------------------- ### Avro JSON Schema Representation Source: https://rfl.getml.com/supported_formats/avro Example of the JSON schema representation for a 'Person' struct, as generated by reflect-cpp for Avro serialization. It defines the record structure, fields, and their types. ```json {"type":"record","name":"Person","fields":[{"name":"first_name","type":{"type":"string"}},{"name":"last_name","type":{"type":"string"}},{"name":"birthday","type":{"type":"string"}},{"name":"children","type":{"type":"array","items":{"type":"Person"},"default":[]}}]} ``` -------------------------------- ### Compile Tests with JSON (CMake) Source: https://rfl.getml.com/contributing Shows how to configure and build the project with JSON serialization tests enabled using CMake. It specifies the build type and enables the test suite. ```cmake cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DREFLECTCPP_BUILD_TESTS=ON cmake --build build -j 4 # gcc, clang cmake --build build --config Release -j 4 # MSVC ``` -------------------------------- ### Initializing and Serializing DecisionTree with rfl::Box Source: https://rfl.getml.com/rfl_ref Shows how to create instances of the 'DecisionTree' struct using rfl::make_box and then serialize it to a JSON string using rfl::json::write. ```c++ auto leaf1 = DecisionTree::Leaf{.value = 3.0}; auto leaf2 = DecisionTree::Leaf{.value = 5.0}; auto node = DecisionTree::Node{.critical_value = 10.0, .lesser = rfl::make_box(leaf1), .greater = rfl::make_box(leaf2)}; const DecisionTree tree{.leaf_or_node = std::move(node)}; const auto json_string = rfl::json::write(tree); ``` -------------------------------- ### Run JSON Tests (Shell) Source: https://rfl.getml.com/contributing Command to execute the compiled JSON serialization tests for the reflect-cpp project. ```shell ./build/tests/json/reflect-cpp-json-tests ``` -------------------------------- ### Getting Tuple Size with rfl::tuple_size_v Source: https://rfl.getml.com/rfl_tuple Shows how to obtain the number of elements in an rfl::Tuple using the rfl::tuple_size_v value. This provides the compile-time size of the tuple. ```C++ #include int main() { auto my_tuple = rfl::make_tuple(1, "hello", 3.14); constexpr auto tuple_size = rfl::tuple_size_v; static_assert(tuple_size == 3); return 0; } ``` -------------------------------- ### Creating and Populating rfl::Object in C++ Source: https://rfl.getml.com/object Demonstrates how to create an rfl::Object and populate it with key-value pairs using the assignment operator. This is analogous to how one might initialize a map or a JSON object. ```C++ auto bart = rfl::Object(); bart["first_name"] = "Bart"; bart["last_name"] = "Simpson"; bart["town"] = "Springfield"; ``` -------------------------------- ### Run Tests for All Serialization Formats (Shell) Source: https://rfl.getml.com/contributing Executes the compiled tests for various serialization formats, including BSON, CBOR, FlexBuffers, MessagePack, JSON, TOML, UBJSON, XML, and YAML. ```shell ./build/tests/bson/reflect-cpp-bson-tests ./build/tests/cbor/reflect-cpp-cbor-tests ./build/tests/flexbuffers/reflect-cpp-flexbuffers-tests ./build/tests/msgpack/reflect-cpp-msgpack-tests ./build/tests/json/reflect-cpp-json-tests ./build/tests/toml/reflect-cpp-toml-tests ./build/tests/ubjson/reflect-cpp-ubjson-tests ./build/tests/xml/reflect-cpp-xml-tests ./build/tests/yaml/reflect-cpp-yaml-tests ``` -------------------------------- ### Write Struct to Stream (C++) Source: https://rfl.getml.com/supported_formats/yaml Demonstrates writing a C++ struct instance to an std::ostream using reflect-cpp's yaml::write function. Includes an example with std::cout. ```C++ const auto person = Person{...}; rfl::yaml::write(person, my_ostream); rfl::yaml::write(person, std::cout) << std::endl; ``` -------------------------------- ### Creating and Populating rfl::Generic Objects Source: https://rfl.getml.com/generic Demonstrates how to create `rfl::Generic` objects and populate them with data, including nested structures like arrays of objects, mirroring JSON creation. ```cpp auto bart = rfl::Generic::Object(); bart["first_name"] = "Bart"; bart["last_name"] = "Simpson"; bart["age"] = 10; auto lisa = rfl::Generic::Object(); lisa["first_name"] = "Lisa"; lisa["last_name"] = "Simpson"; lisa["age"] = 8; auto maggie = rfl::Generic::Object(); maggie["first_name"] = "Lisa"; maggie["last_name"] = "Simpson"; maggie["age"] = 0; auto homer = rfl::Generic::Object(); homer["first_name"] = "Homer"; homer["last_name"] = "Simpson"; homer["age"] = 45; homer["children"] = rfl::Generic::Array({bart, lisa, maggie}); ``` -------------------------------- ### Compile Tests with All Serialization Formats (CMake) Source: https://rfl.getml.com/contributing Configures and builds the project to include tests for multiple serialization formats beyond JSON, such as BSON, CBOR, MessagePack, XML, TOML, UBJSON, and YAML. ```cmake cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_CBOR=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_MSGPACK=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_TOML=ON -DREFLECTCPP_UBJSON=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release cmake --build build -j 4 # gcc, clang cmake --build build --config Release -j 4 # MSVC ``` -------------------------------- ### Reading a Vector of Configurations with rfl::Result (C++) Source: https://rfl.getml.com/result Shows how to parse a vector of user-supplied configurations, allowing individual configurations to contain errors without stopping the entire process. Each configuration is wrapped in rfl::Result. ```cpp const auto configs = rfl::json::read>(json_string); ``` ```cpp const auto configs = rfl::json::read>>(json_string); ``` -------------------------------- ### Access and format rfl::Timestamp data Source: https://rfl.getml.com/timestamps Illustrates how to retrieve the underlying std::tm struct from an rfl::Timestamp object using `.tm()` and how to get its string representation using `.str()`. ```cpp const std::tm birthday = person1.birthday.tm(); std::cout << person1.birthday.str() << std::endl; ``` -------------------------------- ### Getting Tuple Element Type with rfl::tuple_element_t Source: https://rfl.getml.com/rfl_tuple Demonstrates how to retrieve the type of a specific element within an rfl::Tuple using the rfl::tuple_element_t type trait. This is useful for compile-time type manipulation. ```C++ #include #include int main() { auto my_tuple = rfl::make_tuple(1, "hello"); using first_element_type = rfl::tuple_element_t<0, decltype(my_tuple)>; static_assert(std::is_same_v); using second_element_type = rfl::tuple_element_t<1, decltype(my_tuple)>; static_assert(std::is_same_v); return 0; } ``` -------------------------------- ### Combine Processors: SnakeCaseToCamelCase and AddStructName Source: https://rfl.getml.com/concepts/processors Shows how to combine multiple processors, such as `rfl::SnakeCaseToCamelCase` and `rfl::AddStructName`, for more complex JSON transformations. It also demonstrates a more convenient way to group processors using `rfl::Processors`. ```cpp const auto json_string = rfl::json::write>(homer); const auto homer2 = rfl::json::read>(json_string).value(); ``` ```cpp using Processors = rfl::Processors< rfl::SnakeCaseToCamelCase, rfl::AddStructName<"type">>; const auto json_string = rfl::json::write(homer); const auto homer2 = rfl::json::read(json_string).value(); ``` -------------------------------- ### Unsupported Variant Types in Parquet with RFL Source: https://rfl.getml.com/supported_formats/parquet Shows examples of variant types (`std::variant`, `rfl::Variant`, `rfl::TaggedUnion`) that are not supported for serialization to Parquet format using RFL. These types will lead to compilation errors. ```C++ // ❌ This will NOT work struct Person { std::string first_name; std::variant status; // Variant - not supported rfl::Variant type; // rfl::Variant - not supported rfl::TaggedUnion<"type", std::string, int> category; // TaggedUnion - not supported }; ``` -------------------------------- ### Creating and Accessing rfl::Tuple Elements Source: https://rfl.getml.com/rfl_tuple Demonstrates how to create and access elements within an rfl::Tuple using standard library-like functions. These functions provide the same interface as their std::tuple counterparts, ensuring a familiar usage pattern. ```C++ #include int main() { auto my_tuple = rfl::make_tuple(1, "hello", 3.14); int first_element = rfl::get<0>(my_tuple); const char* second_element = rfl::get<1>(my_tuple); double third_element = rfl::get<2>(my_tuple); // std::get also works with rfl::Tuple int first_element_std = std::get<0>(my_tuple); return 0; } ``` -------------------------------- ### Read/Write Person Struct with reflect-cpp Flexbuffers Source: https://rfl.getml.com/supported_formats/flexbuffers Shows a simple example of serializing a 'Person' struct, which includes nested vectors and a custom timestamp type, into bytes using `rfl::flexbuf::write` and deserializing it back with `rfl::flexbuf::read`. ```cpp struct Person { std::string first_name; std::string last_name; rfl::Timestamp<"%Y-%m-%d"> birthday; std::vector children; }; ``` ```cpp const auto person = Person{...}; const auto bytes = rfl::flexbuf::write(person); ``` ```cpp const rfl::Result result = rfl::flexbuf::read(bytes); ``` -------------------------------- ### CMake Configuration for XML Source: https://rfl.getml.com/supported_formats/xml This command demonstrates how to enable XML support when compiling reflect-cpp using CMake. This flag ensures that the XML integration is built correctly. ```bash cmake -DREFLECTCPP_XML=ON .. ``` -------------------------------- ### Write Person to UBJSON stream Source: https://rfl.getml.com/supported_formats/ubjson Shows how to write a C++ 'Person' object to an output stream (e.g., std::ostream) using reflect-cpp's UBJSON write function. Also includes an example with std::cout for debugging. ```cpp const auto person = Person{...}; rfl::ubjson::write(person, my_ostream); rfl::ubjson::write(person, std::cout) << std::endl; ``` -------------------------------- ### Example JSON Output with Optional Fields Source: https://rfl.getml.com/optional_fields This JSON string represents a 'Person' object with a 'children' field containing an array of nested 'Person' objects. Fields that were not explicitly set or were optional and null are omitted or represented appropriately in the output. ```json {"firstName":"Homer","lastName":"Simpson","children":[{"firstName":"Bart","lastName":"Simpson"},{"firstName":"Lisa","lastName":"Simpson"},{"firstName":"Maggie","lastName":"Simpson"}]} ``` -------------------------------- ### Enable reflect-cpp Parsing for Map-Like Containers (gtl::flat_hash_map) Source: https://rfl.getml.com/custom_parser Provides template specializations to enable reflect-cpp's parsing capabilities for `gtl::flat_hash_map`, including marking it as map-like and specializing the `Parser` for different key-value types. ```cpp namespace rfl { namespace parsing { template class is_map_like> : public std::true_type {}; template requires AreReaderAndWriter> struct Parser, ProcessorsType> : public MapParser, ProcessorsType> {}; template requires AreReaderAndWriter> struct Parser, ProcessorsType> : public VectorParser, ProcessorsType> {}; } // namespace parsing } ``` -------------------------------- ### Safely parse rfl::Timestamp from string Source: https://rfl.getml.com/timestamps Provides an example of using `Timestamp<...>::from_string(...)` to safely parse date strings into rfl::Timestamp objects, returning a Result type to handle potential parsing errors. ```cpp const rfl::Result> result = rfl::Timestamp<"%Y-%m-%d">::from_string("1970-01-01"); const rfl::Result> error = rfl::Timestamp<"%Y-%m-%d">::from_string("not a proper time format"); ``` -------------------------------- ### RFL TaggedUnion for API Versioning Source: https://rfl.getml.com/backwards_compatability Demonstrates using `rfl::TaggedUnion` to manage different API versions. Each version is defined with a `Tag` using `rfl::Literal`, allowing for clear version identification within the union. ```c++ struct API_v_1_0 { using Tag = rfl::Literal<"v1.0">; ... }; struct API_v_1_1 { using Tag = rfl::Literal<"v1.1">; ... }; using APIs = rfl::TaggedUnion<"version", API_v_1_0, API_v_1_1, ...>; ``` -------------------------------- ### Create and Use Struct View with rfl::to_view Source: https://rfl.getml.com/to_view Demonstrates creating a view on a Person struct using rfl::to_view, accessing and modifying fields by index and name. This function is part of the rfl_getml library. ```cpp auto lisa = Person{.first_name = "Lisa", .last_name = "Simpson", .age = 8}; const auto view = rfl::to_view(lisa); // Assigns the first field, thus modifying the struct 'lisa'. *view.get<0>() = "Maggie"; // view.values() is a std::tuple containing // pointers to the original fields. *std::get<1>(view.values()) = "Simpson"; // You can also access fields by their name. // The correctness will be ensured at compile time. *view.get<"age">() = 0; // You can also access fields like this. *rfl::get<0>(view) = "Maggie"; // Or like this. *rfl::get<"first_name">(view) = "Maggie"; ``` -------------------------------- ### Implement Custom YAML Constructor (C++) Source: https://rfl.getml.com/supported_formats/yaml Provides the implementation for the 'from_yaml_obj' static method, demonstrating how to parse the YAML input and convert it into the target struct using reflect-cpp. ```C++ rfl::Result Person::from_yaml_obj(const YAMLVar& _obj) { const auto from_nt = [](auto&& _nt) { return rfl::from_named_tuple(std::move(_nt)); }; return rfl::yaml::read>(_obj) .transform(from_nt); } ``` -------------------------------- ### Define Custom Parser with rfl::parsing::CustomParser Source: https://rfl.getml.com/custom_parser This C++ code demonstrates how to implement a custom parser for `YourOriginalClass` using `rfl::parsing::CustomParser`. It defines a template specialization for `Parser` that inherits from `CustomParser`, specifying the reader, writer, original class, and a helper struct (`YourHelperStruct`). ```cpp namespace rfl::parsing { template struct Parser : public CustomParser {}; } // namespace rfl::parsing ``` -------------------------------- ### Serialize C++ struct with XML content field (rfl_getml) Source: https://rfl.getml.com/supported_formats/xml Illustrates using the 'xml_content' field in rfl_getml to directly insert string values into the XML content. This is useful for elements that contain mixed content or text directly. The example shows a struct with 'xml_content' and fields marked as attributes. ```cpp struct Person { std::string xml_content; rfl::Attribute town = "Springfield"; rfl::Attribute> birthday; rfl::Attribute email; std::vector child; }; const auto bart = Person{.xml_content = "Bart Simpson", ``` -------------------------------- ### Unsupported variant types for CSV serialization in C++ Source: https://rfl.getml.com/supported_formats/csv This example illustrates that variant types like `std::variant`, `rfl::Variant`, and `rfl::TaggedUnion` are not supported for CSV serialization into separate columns. The `rfl` library or similar serialization mechanisms will not handle these types correctly for CSV output. ```cpp #include #include // Assuming rfl library is included and configured struct Person { std::string first_name; std::variant status; // Variant - not supported rfl::Variant type; // rfl::Variant - not supported rfl::TaggedUnion<"type", std::string, int> category; // TaggedUnion - not supported }; // ❌ This will NOT work ``` -------------------------------- ### RFL Variant for External API Versioning Source: https://rfl.getml.com/backwards_compatability Illustrates API versioning using `rfl::Variant` with `rfl::Field`. Each API version is associated with a unique field name, providing an externally tagged approach to version management. ```c++ struct API_v_1_0 { ... }; struct API_v_1_1 { ... }; using APIs = rfl::Variant, rfl::Field<"v1.1", API_v_1_1>, ...>; ``` -------------------------------- ### Applying Processors with rfl::from_generic Source: https://rfl.getml.com/generic Demonstrates applying transformation processors, such as `rfl::SnakeCaseToCamelCase`, when converting an `rfl::Generic` object back into a C++ struct. ```cpp assert(rfl::json::read(my_json_string).value() == rfl::from_generic(rfl::json::read(my_json_string).value()).value()); ``` -------------------------------- ### Applying Processors with rfl::to_generic Source: https://rfl.getml.com/generic Shows how to apply transformation processors, like `rfl::SnakeCaseToCamelCase`, during the conversion of a struct to `rfl::Generic`. ```cpp assert(rfl::json::write(my_struct) == rfl::json::write(rfl::to_generic(my_struct))); ``` -------------------------------- ### Define Custom Class with rfl::Rename for reflect-cpp Source: https://rfl.getml.com/concepts/custom_classes Demonstrates creating a custom class (`Person`) that adheres to reflect-cpp's requirements using an implementation struct (`PersonImpl`) with `rfl::Rename` for field mapping. This setup allows for reflection support by defining `ReflectionType`, a constructor accepting it, and a `reflection` method. ```cpp struct PersonImpl { rfl::Rename<"firstName", std::string> first_name; rfl::Rename<"lastName", std::string> last_name; int age; }; class Person { public: // 1) Publicly define `ReflectionType` using ReflectionType = PersonImpl; // 2) Constructor that accepts your `ReflectionType` Person(const PersonImpl& _impl): impl(_impl) {} ~Person() = default; // 3) Method called `reflection` that returns `ReflectionType` const ReflectionType& reflection() const { return impl; } // ...add some more methods here... private: PersonImpl impl; }; ``` -------------------------------- ### Include XML Header Source: https://rfl.getml.com/supported_formats/xml This snippet shows the necessary header to include for XML support in reflect-cpp. It requires the pugixml library to be available. ```cpp #include ``` -------------------------------- ### Define a Custom String Pattern with rfl::Pattern Source: https://rfl.getml.com/patterns Define a custom string pattern using rfl::Pattern for compile-time validation. This example creates a 'TableName' pattern that only allows uppercase letters and underscores, serving as a safeguard against SQL injection. The pattern is encoded at compile time for strong type safety. ```C++ using TableName = rfl::Pattern; ``` -------------------------------- ### Implement Custom JSON Constructor Source: https://rfl.getml.com/supported_formats/json Provides the implementation for the 'from_json_obj' method, parsing a JSON object into a Person struct using rfl::json::read and rfl::from_named_tuple. ```cpp rfl::Result Person::from_json_obj(const JSONVar& _obj) { const auto from_nt = [](auto&& _nt) { return rfl::from_named_tuple(std::move(_nt)); }; return rfl::json::read>(_obj) .transform(from_nt); } ``` -------------------------------- ### Serialize C++ struct to XML with nodes (rfl_getml) Source: https://rfl.getml.com/supported_formats/xml Serializes a C++ struct 'Person' into an XML string where fields are represented as XML nodes. It utilizes rfl::Rename for field name mapping and rfl::Timestamp for date formatting. The example shows how to define a struct with nested elements and create instances of the struct for serialization. ```cpp using Age = rfl::Validator, rfl::Maximum<130>>; struct Person { rfl::Rename<"firstName", std::string> first_name; rfl::Rename<"lastName", std::string> last_name = "Simpson"; std::string town = "Springfield"; rfl::Timestamp<"%Y-%m-%d"> birthday; Age age; rfl::Email email; std::vector child; }; const auto bart = Person{.first_name = "Bart", .birthday = "1987-04-19", .age = 10, .email = "bart@simpson.com"}; const auto lisa = Person{.first_name = "Lisa", .birthday = "1987-04-19", .age = 8, .email = "lisa@simpson.com"}; const auto maggie = Person{.first_name = "Maggie", .birthday = "1987-04-19", .age = 0, .email = "maggie@simpson.com"}; const auto homer = Person{.first_name = "Homer", .birthday = "1987-04-19", .age = 45, .email = "homer@simpson.com", .child = std::vector({bart, lisa, maggie})}; rfl::xml::write(homer); ``` -------------------------------- ### Define Custom Cap'n Proto Deserializer Source: https://rfl.getml.com/supported_formats/capnproto Defines a custom deserialization function 'from_capnproto' for the 'Person' struct, enabling modular compilation for Cap'n Proto parsing with reflect-cpp. ```cpp struct Person { rfl::Rename<"firstName", std::string> first_name; rfl::Rename<"lastName", std::string> last_name; rfl::Timestamp<"%Y-%m-%d"> birthday; using InputVarType = typename rfl::capnproto::Reader::InputVarType; static rfl::Result from_capnproto(const InputVarType& _obj); }; ``` -------------------------------- ### Serialize C++ struct to XML with attributes (rfl_getml) Source: https://rfl.getml.com/supported_formats/xml Demonstrates serializing a C++ struct 'Person' to XML where fields are represented as XML attributes. This approach is suitable for primitive types like strings, integers, and floats. The example showcases using rfl::Attribute to mark fields for attribute representation and highlights limitations on data types for attributes. ```cpp using Age = rfl::Validator, rfl::Maximum<130>>; struct Person { rfl::Rename<"firstName", rfl::Attribute> first_name; rfl::Rename<"lastName", rfl::Attribute> last_name = "Simpson"; rfl::Attribute town = "Springfield"; rfl::Attribute> birthday; rfl::Attribute age; rfl::Attribute email; std::vector child; }; const auto bart = Person{.first_name = "Bart", .birthday = "1987-04-19", .age = 10, .email = "bart@simpson.com"}; const auto lisa = Person{.first_name = "Lisa", .birthday = "1987-04-19", .age = 8, .email = "lisa@simpson.com"}; const auto maggie = Person{.first_name = "Maggie", .birthday = "1987-04-19", .age = 0, .email = "maggie@simpson.com"}; const auto homer = Person{.first_name = "Homer", .birthday = "1987-04-19", .age = 45, .email = "homer@simpson.com", .child = std::vector({bart, lisa, maggie})}; rfl::xml::write(homer); ``` -------------------------------- ### Initialize Struct using rfl::default_value Source: https://rfl.getml.com/concepts/field_syntax Illustrates initializing a struct field using `rfl::default_value`. This is useful when a field has a default behavior or is optional, and it can be combined with explicit assignments for other fields. ```cpp const auto bart = Person{.first_name = "Bart", .last_name = "Simpson", .children = rfl::default_value}; ```