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]

Reply via email to