This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit 41dd3209657db97a050e5a4b0e28eb7701a52e9a Author: chaokunyang <[email protected]> AuthorDate: Sun Jan 25 11:05:13 2026 +0000 π synced local 'docs/guide/' with remote 'docs/guide/' --- docs/guide/cpp/basic-serialization.md | 85 +++++++++++++++++++++++++++++++---- docs/guide/cpp/index.md | 18 ++++++++ docs/guide/cpp/row-format.md | 44 +++++++++--------- docs/guide/java/row-format.md | 6 +-- docs/guide/python/row-format.md | 6 +-- 5 files changed, 118 insertions(+), 41 deletions(-) diff --git a/docs/guide/cpp/basic-serialization.md b/docs/guide/cpp/basic-serialization.md index e45df7e38..3d331450b 100644 --- a/docs/guide/cpp/basic-serialization.md +++ b/docs/guide/cpp/basic-serialization.md @@ -177,30 +177,97 @@ Common error types: ## The FORY_STRUCT Macro -The `FORY_STRUCT` macro registers a struct for serialization: +The `FORY_STRUCT` macro registers a class for serialization (struct works the +same way): ```cpp -struct MyStruct { +class MyStruct { +public: int32_t x; std::string y; std::vector<int32_t> z; + FORY_STRUCT(MyStruct, x, y, z); }; +``` + +Private fields are supported when the macro is placed in a `public:` section: + +```cpp +class PrivateUser { +public: + PrivateUser(int32_t id, std::string name) : id_(id), name_(std::move(name)) {} + + bool operator==(const PrivateUser &other) const { + return id_ == other.id_ && name_ == other.name_; + } + +private: + int32_t id_ = 0; + std::string name_; -// Must be in the same namespace as the struct -FORY_STRUCT(MyStruct, x, y, z); +public: + FORY_STRUCT(PrivateUser, id_, name_); +}; ``` The macro: 1. Generates compile-time field metadata -2. Enables ADL (Argument-Dependent Lookup) for serialization +2. Enables member or ADL (Argument-Dependent Lookup) discovery for serialization 3. Creates efficient serialization code via template specialization **Requirements:** -- Must be placed in the same namespace as the struct (for ADL) +- Must be declared inside the class definition (struct works the same way) or + at namespace scope +- Must be placed after all field declarations (when used inside the class) +- When used inside a class, the macro must be placed in a `public:` section - All listed fields must be serializable types -- Field order in the macro determines serialization order +- Field order in the macro is not important + +## External / Third-Party Types + +When you cannot modify a third-party type, use `FORY_STRUCT` at namespace +scope. This only works with **public** fields. + +```cpp +namespace thirdparty { +struct Foo { + int32_t id; + std::string name; +}; + +FORY_STRUCT(Foo, id, name); +} // namespace thirdparty +``` + +**Limitations:** + +- Must be declared at namespace scope in the same namespace as the type +- Only public fields are supported + +## Inherited Fields + +To include base-class fields in a derived type, use `FORY_BASE(Base)` inside +`FORY_STRUCT`. The base must define its own `FORY_STRUCT` so its fields can be +referenced. + +```cpp +struct Base { + int32_t a; + FORY_STRUCT(Base, a); +}; + +struct Derived : Base { + int32_t b; + FORY_STRUCT(Derived, FORY_BASE(Base), b); +}; +``` + +**Notes:** + +- Base fields are serialized before derived fields. +- Only fields visible from the derived type are supported. ## Nested Structs @@ -209,14 +276,14 @@ Nested structs are fully supported: ```cpp struct Inner { int32_t value; + FORY_STRUCT(Inner, value); }; -FORY_STRUCT(Inner, value); struct Outer { Inner inner; std::string label; + FORY_STRUCT(Outer, inner, label); }; -FORY_STRUCT(Outer, inner, label); // Both must be registered fory.register_struct<Inner>(1); diff --git a/docs/guide/cpp/index.md b/docs/guide/cpp/index.md index fd2cc732a..fefaef00d 100644 --- a/docs/guide/cpp/index.md +++ b/docs/guide/cpp/index.md @@ -188,6 +188,24 @@ int main() { } ``` +### Inherited Fields + +To include base-class fields in a derived type, list `FORY_BASE(Base)` inside +`FORY_STRUCT`. The base must define its own `FORY_STRUCT` so its fields can be +referenced. + +```cpp +struct Base { + int32_t id; + FORY_STRUCT(Base, id); +}; + +struct Derived : Base { + std::string name; + FORY_STRUCT(Derived, FORY_BASE(Base), name); +}; +``` + ## Thread Safety Apache Foryβ’ C++ provides two variants for different threading needs: diff --git a/docs/guide/cpp/row-format.md b/docs/guide/cpp/row-format.md index a3638ab7c..8c410b7e3 100644 --- a/docs/guide/cpp/row-format.md +++ b/docs/guide/cpp/row-format.md @@ -51,16 +51,13 @@ Apache Foryβ’ Row Format is a binary format optimized for: using namespace fory::row; using namespace fory::row::encoder; -// Define a struct struct Person { int32_t id; std::string name; float score; + FORY_STRUCT(Person, id, name, score); }; -// Register field metadata (required for row encoding) -FORY_FIELD_INFO(Person, id, name, score); - int main() { // Create encoder RowEncoder<Person> encoder; @@ -94,12 +91,11 @@ The `RowEncoder<T>` template class provides type-safe encoding: ```cpp #include "fory/encoder/row_encoder.h" -// Define struct with FORY_FIELD_INFO struct Point { double x; double y; + FORY_STRUCT(Point, x, y); }; -FORY_FIELD_INFO(Point, x, y); // Create encoder RowEncoder<Point> encoder; @@ -122,14 +118,14 @@ auto row = encoder.GetWriter().ToRow(); struct Address { std::string city; std::string country; + FORY_STRUCT(Address, city, country); }; -FORY_FIELD_INFO(Address, city, country); struct Person { std::string name; Address address; + FORY_STRUCT(Person, name, address); }; -FORY_FIELD_INFO(Person, name, address); // Encode nested struct RowEncoder<Person> encoder; @@ -151,8 +147,8 @@ std::string country = address_row->GetString(1); struct Record { std::vector<int32_t> values; std::string label; + FORY_STRUCT(Record, values, label); }; -FORY_FIELD_INFO(Record, values, label); RowEncoder<Record> encoder; Record record{{1, 2, 3, 4, 5}, "test"}; @@ -339,7 +335,7 @@ RowEncodeTrait<std::vector<int32_t>>::Type(); // Returns list(int32()) RowEncodeTrait<std::map<std::string, int32_t>>::Type(); // Returns map(utf8(), int32()) -// Type inference for structs (requires FORY_FIELD_INFO) +// Type inference for structs (requires FORY_STRUCT) RowEncodeTrait<Person>::Type(); // Returns struct_({...}) RowEncodeTrait<Person>::Schema(); // Returns schema({...}) ``` @@ -494,20 +490,20 @@ int32_t id = row.GetInt32(0); ## Supported Types Summary -| C++ Type | Row Type | Fixed Size | -| ------------------------ | ---------------- | ---------- | -| `bool` | `boolean()` | 1 byte | -| `int8_t` | `int8()` | 1 byte | -| `int16_t` | `int16()` | 2 bytes | -| `int32_t` | `int32()` | 4 bytes | -| `int64_t` | `int64()` | 8 bytes | -| `float` | `float32()` | 4 bytes | -| `double` | `float64()` | 8 bytes | -| `std::string` | `utf8()` | Variable | -| `std::vector<T>` | `list(T)` | Variable | -| `std::map<K,V>` | `map(K,V)` | Variable | -| `std::optional<T>` | Inner type | Nullable | -| Struct (FORY_FIELD_INFO) | `struct_({...})` | Variable | +| C++ Type | Row Type | Fixed Size | +| -------------------- | ---------------- | ---------- | +| `bool` | `boolean()` | 1 byte | +| `int8_t` | `int8()` | 1 byte | +| `int16_t` | `int16()` | 2 bytes | +| `int32_t` | `int32()` | 4 bytes | +| `int64_t` | `int64()` | 8 bytes | +| `float` | `float32()` | 4 bytes | +| `double` | `float64()` | 8 bytes | +| `std::string` | `utf8()` | Variable | +| `std::vector<T>` | `list(T)` | Variable | +| `std::map<K,V>` | `map(K,V)` | Variable | +| `std::optional<T>` | Inner type | Nullable | +| Struct (FORY_STRUCT) | `struct_({...})` | Variable | ## Related Topics diff --git a/docs/guide/java/row-format.md b/docs/guide/java/row-format.md index 134b58ee1..eb58646b3 100644 --- a/docs/guide/java/row-format.md +++ b/docs/guide/java/row-format.md @@ -142,19 +142,17 @@ print(foo_row.f4[100000].f1) struct Bar { std::string f1; std::vector<int64_t> f2; + FORY_STRUCT(Bar, f1, f2); }; -FORY_FIELD_INFO(Bar, f1, f2); - struct Foo { int32_t f1; std::vector<int32_t> f2; std::map<std::string, int32_t> f3; std::vector<Bar> f4; + FORY_STRUCT(Foo, f1, f2, f3, f4); }; -FORY_FIELD_INFO(Foo, f1, f2, f3, f4); - fory::encoder::RowEncoder<Foo> encoder; encoder.Encode(foo); auto row = encoder.GetWriter().ToRow(); diff --git a/docs/guide/python/row-format.md b/docs/guide/python/row-format.md index c0cc57beb..3fd86f9f3 100644 --- a/docs/guide/python/row-format.md +++ b/docs/guide/python/row-format.md @@ -121,19 +121,17 @@ Bar bar2 = barEncoder.fromRow(f4Array.getStruct(20)); // Deserialize 21st Ba struct Bar { std::string f1; std::vector<int64_t> f2; + FORY_STRUCT(Bar, f1, f2); }; -FORY_FIELD_INFO(Bar, f1, f2); - struct Foo { int32_t f1; std::vector<int32_t> f2; std::map<std::string, int32_t> f3; std::vector<Bar> f4; + FORY_STRUCT(Foo, f1, f2, f3, f4); }; -FORY_FIELD_INFO(Foo, f1, f2, f3, f4); - fory::encoder::RowEncoder<Foo> encoder; encoder.Encode(foo); auto row = encoder.GetWriter().ToRow(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
