This document provides a comprehensive overview of Cista++, a high-performance, single-header C++17 library designed for simple serialization and reflection. The library's core philosophy is to offer raw performance with minimal overhead by working directly with native C++ data structures, eliminating the need for macros or source code generation.
Key features include support for complex, cyclic, and recursive data structures, and memory-efficient serialization directly to the filesystem using memory-mapped files. Cista++ is rigorously tested through continuous fuzzing and provides optional features for data integrity, such as checksums and automatic data structure versioning via type hashing. The library also includes high-performance, serializable containers like a hash map and hash set based on Google's Swiss Table. Its reflection mechanism significantly reduces boilerplate by automatically deriving hashing and equality functions. Benchmarks indicate that Cista++ excels in serialization speed and produces a compact output size compared to alternatives like Cap’n Proto and Flatbuffers, making it ideal for applications like asset loading, shared memory, and high-speed data transfer where cross-language compatibility is not a primary requirement.
Cista++: A Deep Dive into the High-Performance C++ Serialization Library
Core Philosophy & Features:
Simplicity: Cista++ is a single-header library with no external dependencies, no macros, and no code generation steps, making it easy to integrate into any C++17 project.
High Performance: It is designed for maximum speed by serializing and deserializing native C++ structs directly, avoiding intermediate representations.
Memory Efficiency: The library supports serializing directly to the filesystem or memory-mapped files, which can save up to 50% of memory by avoiding the need for an intermediate buffer.
Advanced Data Structures: It natively handles complex and cyclic data structures, including recursive types and pointers, which are often challenging for other serialization libraries.
Robustness and Safety:
Data Integrity: Offers optional checksums (cista::mode::WITH_INTEGRITY) to verify data integrity and prevent the deserialization of corrupt files.
Versioning: Includes built-in optional data structure versioning (cista::mode::WITH_VERSION) through recursive type hashing, ensuring that the data being deserialized matches the expected structure.
Security: The library is continuously checked for vulnerabilities using LLVM's LibFuzzer to ensure safe handling of untrusted data.
Reflection and Code Reduction:
Boilerplate Elimination: The underlying reflection mechanism can automatically derive hash and equality functions for complex user-defined structs (auto cista_members()). This simplifies the use of custom types in hash-based containers.
Non-Aggregate Support: It supports non-aggregate types, such as classes with custom constructors or inheritance, through a simple cista_members() member function that exposes the fields to be serialized.
Built-in Containers and Utilities:
High-Performance Hash Containers: Provides serializable hash_map and hash_set implementations based on the highly efficient Google's Swiss Table design.
Configurable Hashing: The hashing algorithm is configurable via CMake, with support for FNV1A (default), XXH3, and WYHASH for different performance trade-offs.
Comprehensive Data Structures: The library includes a suite of serializable containers such as vector, string, unique_ptr, rtree, bitset, bitvec, and fws_multimap.
Performance Benchmarks:
Serialization Speed: Benchmarks show Cista++ is exceptionally fast, outperforming libraries like Cap’n Proto, cereal, and Flatbuffers in serialization time (72 ms in the example benchmark).
Compact Size: It produces a significantly smaller serialized output (25.3M) compared to its competitors in the same benchmark.
Fast Deserialization & Traversal: Offers near-instantaneous "fast deserialize" by directly mapping the data, with combined deserialization and traversal performance on par with Cap’n Proto and Flatbuffers.
Use Cases and Limitations:
Ideal Applications: Best suited for asset loading in games or GIS, transferring data over a network between C++ applications, and for shared memory IPC.
Known Limitations: It is not intended for scenarios requiring cross-language compatibility or long-term protocol evolution (downward compatibility). For such cases, alternatives like Protocol Buffers or Flatbuffers are recommended.
System Constraints: The reader and writer are expected to have the same pointer width (e.g., both 64-bit). Cross-endianess (big vs. little endian) is supported.
License and Contribution:
Open Source: The library is available under the permissive MIT License, allowing for free use in both open-source and commercial projects.
Community: Contributions in the form of bug reports and pull requests are encouraged.