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


The following commit(s) were added to refs/heads/main by this push:
     new a986c0404 πŸ”„ synced local 'docs/docs/guide/' with remote 'docs/guide/'
a986c0404 is described below

commit a986c0404cede67b79647d4048e0e8bdc4a3187b
Author: chaokunyang <[email protected]>
AuthorDate: Thu Dec 25 05:34:02 2025 +0000

    πŸ”„ synced local 'docs/docs/guide/' with remote 'docs/guide/'
---
 docs/docs/guide/cpp/cross-language.md      |   2 +-
 docs/docs/guide/cpp/field-configuration.md | 291 +++++++++++++++++++++++++++++
 docs/docs/guide/cpp/index.md               |   1 +
 docs/docs/guide/cpp/row-format.md          |   2 +-
 docs/docs/guide/cpp/supported-types.md     |   2 +-
 5 files changed, 295 insertions(+), 3 deletions(-)

diff --git a/docs/docs/guide/cpp/cross-language.md 
b/docs/docs/guide/cpp/cross-language.md
index 3bf81cdae..dfc03e9b5 100644
--- a/docs/docs/guide/cpp/cross-language.md
+++ b/docs/docs/guide/cpp/cross-language.md
@@ -1,6 +1,6 @@
 ---
 title: Cross-Language Serialization
-sidebar_position: 6
+sidebar_position: 7
 id: cpp_cross_language
 license: |
   Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/docs/docs/guide/cpp/field-configuration.md 
b/docs/docs/guide/cpp/field-configuration.md
new file mode 100644
index 000000000..a36b83226
--- /dev/null
+++ b/docs/docs/guide/cpp/field-configuration.md
@@ -0,0 +1,291 @@
+---
+title: Field Configuration
+sidebar_position: 5
+id: cpp_field_configuration
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page explains how to configure field-level metadata for serialization.
+
+## Overview
+
+Apache Foryβ„’ provides two ways to specify field-level metadata at compile time:
+
+1. **`fory::field<>` template** - Inline metadata in struct definition
+2. **`FORY_FIELD_TAGS` macro** - Non-invasive metadata added separately
+
+These enable:
+
+- **Tag IDs**: Assign compact numeric IDs for schema evolution
+- **Nullability**: Mark pointer fields as nullable
+- **Reference Tracking**: Enable reference tracking for shared pointers
+
+## The fory::field Template
+
+```cpp
+template <typename T, int16_t Id, typename... Options>
+class field;
+```
+
+### Template Parameters
+
+| Parameter | Description                                      |
+| --------- | ------------------------------------------------ |
+| `T`       | The underlying field type                        |
+| `Id`      | Field tag ID (int16_t) for compact serialization |
+| `Options` | Optional tags: `fory::nullable`, `fory::ref`     |
+
+### Basic Usage
+
+```cpp
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+struct Person {
+  fory::field<std::string, 0> name;
+  fory::field<int32_t, 1> age;
+  fory::field<std::optional<std::string>, 2> nickname;
+};
+FORY_STRUCT(Person, name, age, nickname);
+```
+
+The `fory::field<>` wrapper is transparent - you can use it like the 
underlying type:
+
+```cpp
+Person person;
+person.name = "Alice";           // Direct assignment
+person.age = 30;
+std::string n = person.name;     // Implicit conversion
+int a = person.age.get();        // Explicit get()
+```
+
+## Tag Types
+
+### fory::nullable
+
+Marks a smart pointer field as nullable (can be `nullptr`):
+
+```cpp
+struct Node {
+  fory::field<std::string, 0> name;
+  fory::field<std::shared_ptr<Node>, 1, fory::nullable> next;  // Can be 
nullptr
+};
+FORY_STRUCT(Node, name, next);
+```
+
+**Valid for:** `std::shared_ptr<T>`, `std::unique_ptr<T>`
+
+**Note:** For nullable primitives or strings, use `std::optional<T>` instead:
+
+```cpp
+// Correct: use std::optional for nullable primitives
+fory::field<std::optional<int32_t>, 0> optional_value;
+
+// Wrong: nullable is not allowed for primitives
+// fory::field<int32_t, 0, fory::nullable> value;  // Compile error!
+```
+
+### fory::not_null
+
+Explicitly marks a pointer field as non-nullable. This is the default for 
smart pointers, but can be used for documentation:
+
+```cpp
+fory::field<std::shared_ptr<Data>, 0, fory::not_null> data;  // Must not be 
nullptr
+```
+
+**Valid for:** `std::shared_ptr<T>`, `std::unique_ptr<T>`
+
+### fory::ref
+
+Enables reference tracking for shared pointer fields. When multiple fields 
reference the same object, it will be serialized once and shared:
+
+```cpp
+struct Graph {
+  fory::field<std::string, 0> name;
+  fory::field<std::shared_ptr<Graph>, 1, fory::ref> left;    // Ref tracked
+  fory::field<std::shared_ptr<Graph>, 2, fory::ref> right;   // Ref tracked
+};
+FORY_STRUCT(Graph, name, left, right);
+```
+
+**Valid for:** `std::shared_ptr<T>` only (requires shared ownership)
+
+### Combining Tags
+
+Multiple tags can be combined for shared pointers:
+
+```cpp
+// Nullable + ref tracking
+fory::field<std::shared_ptr<Node>, 0, fory::nullable, fory::ref> link;
+```
+
+## Type Rules
+
+| Type                 | Allowed Options   | Nullability                       
 |
+| -------------------- | ----------------- | 
---------------------------------- |
+| Primitives, strings  | None              | Use `std::optional<T>` if 
nullable |
+| `std::optional<T>`   | None              | Inherently nullable               
 |
+| `std::shared_ptr<T>` | `nullable`, `ref` | Non-null by default               
 |
+| `std::unique_ptr<T>` | `nullable`        | Non-null by default               
 |
+
+## Complete Example
+
+```cpp
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+// Define a struct with various field configurations
+struct Document {
+  // Required fields (non-nullable)
+  fory::field<std::string, 0> title;
+  fory::field<int32_t, 1> version;
+
+  // Optional primitive using std::optional
+  fory::field<std::optional<std::string>, 2> description;
+
+  // Nullable pointer
+  fory::field<std::unique_ptr<std::string>, 3, fory::nullable> metadata;
+
+  // Reference-tracked shared pointer
+  fory::field<std::shared_ptr<Document>, 4, fory::ref> parent;
+
+  // Nullable + reference-tracked
+  fory::field<std::shared_ptr<Document>, 5, fory::nullable, fory::ref> related;
+};
+FORY_STRUCT(Document, title, version, description, metadata, parent, related);
+
+int main() {
+  auto fory = Fory::builder().xlang(true).build();
+  fory.register_struct<Document>(100);
+
+  Document doc;
+  doc.title = "My Document";
+  doc.version = 1;
+  doc.description = "A sample document";
+  doc.metadata = nullptr;  // Allowed because nullable
+  doc.parent = std::make_shared<Document>();
+  doc.parent->title = "Parent Doc";
+  doc.related = nullptr;  // Allowed because nullable
+
+  auto bytes = fory.serialize(doc).value();
+  auto decoded = fory.deserialize<Document>(bytes).value();
+}
+```
+
+## Compile-Time Validation
+
+Invalid configurations are caught at compile time:
+
+```cpp
+// Error: nullable and not_null are mutually exclusive
+fory::field<std::shared_ptr<int>, 0, fory::nullable, fory::not_null> bad1;
+
+// Error: nullable only valid for smart pointers
+fory::field<int32_t, 0, fory::nullable> bad2;
+
+// Error: ref only valid for shared_ptr
+fory::field<std::unique_ptr<int>, 0, fory::ref> bad3;
+
+// Error: options not allowed for std::optional (inherently nullable)
+fory::field<std::optional<int>, 0, fory::nullable> bad4;
+```
+
+## Backwards Compatibility
+
+Existing structs without `fory::field<>` wrappers continue to work:
+
+```cpp
+// Old style - still works
+struct LegacyPerson {
+  std::string name;
+  int32_t age;
+};
+FORY_STRUCT(LegacyPerson, name, age);
+
+// New style with field metadata
+struct ModernPerson {
+  fory::field<std::string, 0> name;
+  fory::field<int32_t, 1> age;
+};
+FORY_STRUCT(ModernPerson, name, age);
+```
+
+## FORY_FIELD_TAGS Macro
+
+The `FORY_FIELD_TAGS` macro provides a non-invasive way to add field metadata 
without modifying struct definitions. This is useful for:
+
+- **Third-party types**: Add metadata to types you don't own
+- **Clean structs**: Keep struct definitions as pure C++
+- **Isolated dependencies**: Confine Fory headers to serialization config files
+
+### Usage
+
+```cpp
+// user_types.h - NO fory headers needed!
+struct Document {
+  std::string title;
+  int32_t version;
+  std::optional<std::string> description;
+  std::shared_ptr<User> author;
+  std::shared_ptr<User> reviewer;
+  std::shared_ptr<Document> parent;
+  std::unique_ptr<Data> data;
+};
+
+// serialization_config.cpp - fory config isolated here
+#include "fory/serialization/fory.h"
+#include "user_types.h"
+
+FORY_STRUCT(Document, title, version, description, author, reviewer, parent, 
data)
+
+FORY_FIELD_TAGS(Document,
+  (title, 0),                      // string: non-nullable
+  (version, 1),                    // int: non-nullable
+  (description, 2),                // optional: inherently nullable
+  (author, 3),                     // shared_ptr: non-nullable (default)
+  (reviewer, 4, nullable),         // shared_ptr: nullable
+  (parent, 5, ref),                // shared_ptr: non-nullable, with ref 
tracking
+  (data, 6, nullable)              // unique_ptr: nullable
+)
+```
+
+### FORY_FIELD_TAGS Options
+
+| Field Type           | Valid Combinations                                    
                                   |
+| -------------------- | 
----------------------------------------------------------------------------------------
 |
+| Primitives, strings  | `(field, id)` only                                    
                                   |
+| `std::optional<T>`   | `(field, id)` only                                    
                                   |
+| `std::shared_ptr<T>` | `(field, id)`, `(field, id, nullable)`, `(field, id, 
ref)`, `(field, id, nullable, ref)` |
+| `std::unique_ptr<T>` | `(field, id)`, `(field, id, nullable)`                
                                   |
+
+### API Comparison
+
+| Aspect                  | `fory::field<>` Wrapper  | `FORY_FIELD_TAGS` Macro 
|
+| ----------------------- | ------------------------ | ----------------------- 
|
+| **Struct definition**   | Modified (wrapped types) | Unchanged (pure C++)    
|
+| **IDE support**         | Template noise           | Excellent (clean types) 
|
+| **Third-party classes** | Not supported            | Supported               
|
+| **Header dependencies** | Required everywhere      | Isolated to config      
|
+| **Migration effort**    | High (change all fields) | Low (add one macro)     
|
+
+## Related Topics
+
+- [Type Registration](type-registration.md) - Registering types with 
FORY_STRUCT
+- [Schema Evolution](schema-evolution.md) - Using tag IDs for schema evolution
+- [Configuration](configuration.md) - Enabling reference tracking globally
diff --git a/docs/docs/guide/cpp/index.md b/docs/docs/guide/cpp/index.md
index b623d6e00..85a5beaca 100644
--- a/docs/docs/guide/cpp/index.md
+++ b/docs/docs/guide/cpp/index.md
@@ -242,6 +242,7 @@ std::thread t2([&]() {
 - [Basic Serialization](basic-serialization.md) - Object graph serialization
 - [Schema Evolution](schema-evolution.md) - Compatible mode and schema changes
 - [Type Registration](type-registration.md) - Registering types
+- [Field Configuration](field-configuration.md) - Field-level metadata 
(nullable, ref tracking)
 - [Supported Types](supported-types.md) - All supported types
 - [Cross-Language](cross-language.md) - XLANG mode
 - [Row Format](row-format.md) - Zero-copy row-based format
diff --git a/docs/docs/guide/cpp/row-format.md 
b/docs/docs/guide/cpp/row-format.md
index 62e405dd4..44fbef776 100644
--- a/docs/docs/guide/cpp/row-format.md
+++ b/docs/docs/guide/cpp/row-format.md
@@ -1,6 +1,6 @@
 ---
 title: Row Format
-sidebar_position: 7
+sidebar_position: 8
 id: cpp_row_format
 license: |
   Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/docs/docs/guide/cpp/supported-types.md 
b/docs/docs/guide/cpp/supported-types.md
index fead3785b..0ea9e576a 100644
--- a/docs/docs/guide/cpp/supported-types.md
+++ b/docs/docs/guide/cpp/supported-types.md
@@ -1,6 +1,6 @@
 ---
 title: Supported Types
-sidebar_position: 5
+sidebar_position: 6
 id: cpp_supported_types
 license: |
   Licensed to the Apache Software Foundation (ASF) under one or more


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to