diff --git a/README.md b/README.md index a8b6b02..075051d 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,25 @@ # 😀CPP Essence -- Modern C++ Utility Library - - [![Windows Build](https://github.com/refvalue/cpp-essence/actions/workflows/windows.yaml/badge.svg)](https://github.com/refvalue/cpp-essence/actions/workflows/windows.yaml)[![Ubuntu Build](https://github.com/refvalue/cpp-essence/actions/workflows/ubuntu.yaml/badge.svg)](https://github.com/refvalue/cpp-essence/actions/workflows/ubuntu.yaml)[![MacOS Build](https://github.com/refvalue/cpp-essence/actions/workflows/macos.yaml/badge.svg)](https://github.com/refvalue/cpp-essence/actions/workflows/macos.yaml) - - ## 📚Requirements - MSVC >= 14.30 (Visual Studio 2022 17.0) - GCC >= 11.2 -- Clang >= 16.0 +- Clang >= 17.0 (Supporting Class Template argument Deduction for Aggregates) - Emscripten >= 3.1.52 -- Host GLIBC >= 2.34 (when compiling on Linux) +- Host GLIBC >= 2.31 (when compiling on Linux) - C++ 20 Support - JDK >= 8 (Optional if `ES_WITH_JNI` = `OFF`) - - ## 💻Importing the Prebuilt Package with CMake ### Step-by-step Configuration -To use this library on your target platform immediately, you can download the prebuilt packages from the [Release](http://www.baidu.com) page. After obtaining the compressed files, such as `cpp-essence-1.0-windows-x86_64-release.zip` and `cpp-essence-1.0-linux-x86_64.tgz`, you can decompress them to any location on your disk. +To use this library on your target platform immediately, you can download the prebuilt packages from +the [Release](http://www.baidu.com) page. After obtaining the compressed files, such as +`cpp-essence-1.0-windows-x86_64-release.zip` and `cpp-essence-1.0-linux-x86_64.tgz`, you can decompress them to any +location on your disk. ```powershell Expand-Archive -Path './cpp-essence-1.0-windows-x86_64-release.zip' -DestinationPath 'C:\path\to\extract\folder' @@ -32,7 +29,8 @@ Expand-Archive -Path './cpp-essence-1.0-windows-x86_64-release.zip' -Destination tar -zxf ./cpp-essence-1.0-linux-x86_64.tgz ``` -Then you need to modify the `CMakeUserPresets.json` file in your own project to add a CMake variable which stores the path of the directory that the file was decompressed to. Here is an example: +Then you need to modify the `CMakeUserPresets.json` file in your own project to add a CMake variable which stores the +path of the directory that the file was decompressed to. Here is an example: ```json { @@ -76,115 +74,149 @@ target_link_libraries(your_target_name PRIVATE CppEssence::cpp-essence) # The ma target_link_libraries(your_target_name PRIVATE CppEssenceJniSupport::cpp-essence-jni-support) # Optional JNI utilities. ``` - - ### Release or Debug Version -Due to the different ABIs between the Release and Debug versions of Microsoft's STL, Windows DLLs that export any STL symbols cannot be mixed. Forcing this will result in severe issues, such as program crashes or unstable running states. To avoid this problem, it is highly recommended to ensure that your DLL has the same build type as this library. - -There is no such issue on Linux/Unix platform, so only the Release version is provided on the [Release](http://www.baidu.com) page. - +Due to the different ABIs between the Release and Debug versions of Microsoft's STL, Windows DLLs that export any STL +symbols cannot be mixed. Forcing this will result in severe issues, such as program crashes or unstable running states. +To avoid this problem, it is highly recommended to ensure that your DLL has the same build type as this library. +There is no such issue on Linux/Unix platform, so only the Release version is provided on +the [Release](http://www.baidu.com) page. ## 💡Main Features ### 1. Reflection Tool Library + - **100% Macro-Free Design**: Implemented using native C++ with no reliance on macros. -- **Data Member Traversal**: Supports direct traversal of class data members, allowing easy access to all member variables. +- **Data Member Traversal**: Supports direct traversal of class data members, allowing easy access to all member + variables. - **Member Name Retrieval**: Automatically retrieves the names of class members. - **Enum Support**: Provides automatic enum-to-string conversion and the ability to read enum ranges. - **JSON Serialization**: Supports automatic serialization and deserialization of class objects to/from JSON. ### 2. Command Line Tool Library + - **GNU/Linux Bash Compliance**: Supports multiple command-line parameter formats, including: - - `--name=value`, `-n=value`, `--name value`, `-n value`, `--switch`, `-s` - - `--values 1,2,3,4,5`, `-v 1,2,3,4,5`, `--values alice,bob,paul`, `-v alice,bob,paul` - - `-abcde` and many more combinations. -- **Array & Enum Parsing**: Supports parsing of array and enum values, with automatic conversion to data models using reflection. + - `--name=value`, `-n=value`, `--name value`, `-n value`, `--switch`, `-s` + - `--values 1,2,3,4,5`, `-v 1,2,3,4,5`, `--values alice,bob,paul`, `-v alice,bob,paul` + - `-abcde` and many more combinations. +- **Array & Enum Parsing**: Supports parsing of array and enum values, with automatic conversion to data models using + reflection. ### 3. Internationalization Support -- **Multi-language Mapping**: Allows the creation of multi-language mapping files, which can be compiled into a compact binary format. + +- **Multi-language Mapping**: Allows the creation of multi-language mapping files, which can be compiled into a compact + binary format. - **Dynamic Language Switching**: Supports runtime switching of languages and fetching of language-specific texts. - **Independent Language Packs**: Supports independent language packs for modular localization without interference. ### 4. Multicast Delegate System -- **Multicast Delegate**: Implements a multi-subscription delegate system similar to C#'s `MulticastDelegate`, enabling thread-safe event triggering and multiple listeners. + +- **Multicast Delegate**: Implements a multi-subscription delegate system similar to C#'s `MulticastDelegate`, enabling + thread-safe event triggering and multiple listeners. ### 5. I/O Basic Support Library + - **C++23 `spanstream` Support**: Implements the C++23 `spanstream` pattern for efficient stream processing. - **File Type Detection**: Supports quick identification of common image types based on file headers. - **Abstract File System Operations**: Provides a unified interface for file system operations across platforms. - **Embedded Resources**: Supports embedded resources with cross-platform compatibility, based on CMRC. ### 6. Networking Library + - **RESTful HTTP Communication**: Supports REST-style HTTP communication. - **Server-Side Events**: Implements Server-Side Events (SSE) for real-time server-client communication. - **File Download with Progress**: Supports downloading files with progress tracking. ### 7. JSON Library -- **nlohmann/json Integration**: Built on the popular `nlohmann json` library, with support for automatic member reflection. + +- **nlohmann/json Integration**: Built on the popular `nlohmann json` library, with support for automatic member + reflection. - **Flexible Naming Conventions**: Supports automatic conversion between `Camel`, `Pascal`, and `Snake` case styles. ### 8. Cryptography Library -- **Symmetric & Asymmetric Encryption**: Supports common cryptographic algorithms, including AES, SM2, SM4, RSA, and elliptic curve cryptography. + +- **Symmetric & Asymmetric Encryption**: Supports common cryptographic algorithms, including AES, SM2, SM4, RSA, and + elliptic curve cryptography. - **Block-Level Encryption**: Provides support for block encryption and decryption for large data. ### 9. Logging System -- **spdlog Integration**: Built on the popular `spdlog` library, with support for logging, log dumping, and log rotation. + +- **spdlog Integration**: Built on the popular `spdlog` library, with support for logging, log dumping, and log + rotation. - **Internationalization Support**: Allows logging messages in multiple languages. ### 10. Data Hashing + - **Multiple Hashing Algorithms**: Supports SHA1, SHA2, SHA3, MD5, SM3, and more. - **Large File Checksums**: Supports checksum calculation for large files with chunk-based hashing. ### 11. JNI Support Library(Optional) + - **Automatic Data Mapping**: Provides automatic mapping of C++ containers and native types to JNI types. - **Custom Java Class Conversion**: Supports custom data conversion rules for Java class types. - **Managed Object Lifecycle**: Allows control over the lifecycle of managed objects in JNI. ### 12. Functional Programming Library -- **Convenient Templates**: Provides functional programming utilities, including function signature reflection and easy-to-use function objects. + +- **Convenient Templates**: Provides functional programming utilities, including function signature reflection and + easy-to-use function objects. - **Concepts Support**: Includes helpful concepts for functional programming in C++. ### 13. Native API Programming Library + - **Handle Management**: Provides RTTI-based management of raw and managed API handles. -- **Custom System Handle Management**: Allows user-defined management of native API calls and handle lifecycle to avoid memory leaks. +- **Custom System Handle Management**: Allows user-defined management of native API calls and handle lifecycle to avoid + memory leaks. ### 14. Hash Utilities + - **Unified Hashing Methods**: Offers unified methods for combining hash values. -- **Case-Insensitive String Comparisons**: Supports case-insensitive string comparisons and dictionary-based string lookups. +- **Case-Insensitive String Comparisons**: Supports case-insensitive string comparisons and dictionary-based string + lookups. ### 15. Formatting Library + - **fmt Library Support**: Built on the popular `fmt` library, offering flexible string formatting options. - **C++20 `format`**: Dynamically wraps the `std::format` library depending on the user's environment. ### 16. String Library -- **Zero-Terminated Strings**: Supports `zstring_view`, a string view type for efficiently passing C-style null-terminated strings. + +- **Zero-Terminated Strings**: Supports `zstring_view`, a string view type for efficiently passing C-style + null-terminated strings. - **C-Style String Support**: Optimized for interop with lower-level C APIs. ### 17. Ranges Adaptation Library + - **C++20 Range Extensions**: Extends C++20 `Ranges` with additional utilities like `join_with` for advanced use cases. - **Comprehensive Functionality**: Enhances the business logic with extended range-based operations. ### 18. ABI Compatibility Library -- **ABI Compatibility**: Facilitates ABI-compatible programming for common types like `vector`, `map`, `list`, `string`, etc. + +- **ABI Compatibility**: Facilitates ABI-compatible programming for common types like `vector`, `map`, `list`, `string`, + etc. - **JSON Support**: Adds seamless integration for JSON data manipulation. ### 19. Graphics Support Library + - **Color Space Support**: Supports ARGB and YUV color spaces, with over a hundred built-in color values. - **Automatic Type Conversion**: Supports automatic conversion between different graphics types. ### 20. Character Encoding Library -- **UTF-8, UTF-16, and Native Encoding**: Supports conversion between UTF-8, UTF-16, and native encodings (`char` or `wchar_t`). + +- **UTF-8, UTF-16, and Native Encoding**: Supports conversion between UTF-8, UTF-16, and native encodings (`char` or + `wchar_t`). - **Comprehensive String Operations**: Provides a wide range of string handling functions. ### 21. Numeric Conversion Library -- **String Conversion**: Provides convenient `from_string` and `to_string` utilities for seamless conversion between various data types and strings. -### 22. Compression Library -- **ZSTD, ZIP, and GZIP**: Supports ZSTD, ZIP, and GZIP compression algorithms for efficient data compression and decompression. +- **String Conversion**: Provides convenient `from_string` and `to_string` utilities for seamless conversion between + various data types and strings. +### 22. Compression Library +- **ZSTD, ZIP, and GZIP**: Supports ZSTD, ZIP, and GZIP compression algorithms for efficient data compression and + decompression. ## 🙋Quick Samples @@ -192,7 +224,11 @@ There is no such issue on Linux/Unix platform, so only the Release version is pr #### Compatibility between `char8_t` and `char` -In C++20, the introduction of the new built-in character type `char8_t` and the `std::u8string` (which is essentially `std::basic_string`) was meant to provide a better and more standardized way to handle UTF-8 encoded characters. However, the decision to **ban implicit conversions between `char8_t` and `char`** has introduced some challenges for developers, especially when migrating legacy code that was designed around `std::string` (which uses `char`) and `std::string_view`. +In C++20, the introduction of the new built-in character type `char8_t` and the `std::u8string` (which is essentially +`std::basic_string`) was meant to provide a better and more standardized way to handle UTF-8 encoded +characters. However, the decision to **ban implicit conversions between `char8_t` and `char`** has introduced some +challenges for developers, especially when migrating legacy code that was designed around `std::string` (which uses +`char`) and `std::string_view`. ```c++ #include @@ -207,9 +243,14 @@ std::string_view strv2 = u8strv; // Ill-formed. #### Proposal P1423R3 -The proposal **P1423R3** introduces a methodology to handle the compatibility problem caused by the introduction of `char8_t` in C++20, particularly regarding the migration of legacy code. It suggests that `char` and `std::string` should be used universally where possible, avoiding the direct use of `char8_t` and `std::u8string` in most cases. This approach aims to ensure that existing libraries and interfaces that rely on `std::string` can continue to function without modification or the need for explicit casting between `char` and `char8_t`. +The proposal **P1423R3** introduces a methodology to handle the compatibility problem caused by the introduction of +`char8_t` in C++20, particularly regarding the migration of legacy code. It suggests that `char` and `std::string` +should be used universally where possible, avoiding the direct use of `char8_t` and `std::u8string` in most cases. This +approach aims to ensure that existing libraries and interfaces that rely on `std::string` can continue to function +without modification or the need for explicit casting between `char` and `char8_t`. -The macro `U8` represents a UTF-8 encoded string literal within this implementation of **P1423R3**. Here’s a simple code block demonstrating how this compatibility could be managed: +The macro `U8` represents a UTF-8 encoded string literal within this implementation of **P1423R3**. Here’s a simple code +block demonstrating how this compatibility could be managed: ```c++ #include @@ -241,7 +282,9 @@ template std::filesystem::path::path(const Source& source, std::filesystem::path::format fmt = std::filesystem::path::auto_format); ``` -Any of the character types `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t` is allowed for the type parameter `Source`. To designate a UTF-8 encoded string precisely, you can call `essence::to_u8string` to convert your `std::string` to `std::u8string` to enable the `char8_t` overload. +Any of the character types `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t` is allowed for the type parameter +`Source`. To designate a UTF-8 encoded string precisely, you can call `essence::to_u8string` to convert your +`std::string` to `std::u8string` to enable the `char8_t` overload. ```c++ #include @@ -251,15 +294,14 @@ Any of the character types `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t` const std::filesystem::path path{essence::to_u8string(U8("/usr/local/etc"))}; // Ensures UTF-8. ``` - - ### 👉Globalization with Dynamic Language Switching To enable multi-language support, you can create the directory structure and files below. 1. **Create the `lang` directory**: This will be the main directory that holds language-specific JSON files. 2. **Create `en-US.json` and `zh-CN.json`**: These files will contain the language-specific text mappings. -3. **Create `CMakeLists.txt`**: This file will include instructions for building the project, especially if you want to handle the language files in the build process. +3. **Create `CMakeLists.txt`**: This file will include instructions for building the project, especially if you want to + handle the language files in the build process. Here is how the directory structure should look: @@ -270,13 +312,13 @@ Here is how the directory structure should look: | |-- CMakeLists.txt ``` -The `en-US.json` contains keyword mappings written in American English. +The `en-US.json` contains keyword mappings written in American English. ```json { - "hello world": "hello world", - "file not found": "The file was not found.", - "illegal pattern": "The regex pattern was illegal." + "hello world": "hello world", + "file not found": "The file was not found.", + "illegal pattern": "The regex pattern was illegal." } ``` @@ -284,9 +326,9 @@ The `zh-CN.json` contains keyword mapping written in Chinese Mandarin. ```json { - "hello world": "你好世界", - "file not found": "文件未找到。", - "illegal pattern": "正则表达式规则无效。" + "hello world": "你好世界", + "file not found": "文件未找到。", + "illegal pattern": "正则表达式规则无效。" } ``` @@ -303,7 +345,8 @@ es_add_lang_resources( ) ``` -To enable globalization integration, you need to rebuild the CMake cache and then the generated header will be available. +To enable globalization integration, you need to rebuild the CMake cache and then the generated header will be +available. ```c++ #include "user_globalization_my_test.hpp" @@ -348,8 +391,6 @@ int main() { } ``` - - ### 👉Reflecting Classes and Enumerations All runtime reflection functions are located in ``. @@ -358,11 +399,16 @@ All compile-time reflection features can be found in ``. #### Background -The C++ Reflection Proposal has not yet been accepted into the standard. However, in modern C++ compilers, there are some "magic" macros that can be evaluated dynamically within a functional context. For example, GCC provides `__PRETTY_FUNCTION__`, which returns a literal string of the enclosing function's signature, while MSVC offers `__FUNCSIG__` with similar functionality. Leveraging the robust compile-time evaluation capabilities introduced in C++20, we can implement a basic reflection library by parsing the output of these macros. +The C++ Reflection Proposal has not yet been accepted into the standard. However, in modern C++ compilers, there are +some "magic" macros that can be evaluated dynamically within a functional context. For example, GCC provides +`__PRETTY_FUNCTION__`, which returns a literal string of the enclosing function's signature, while MSVC offers +`__FUNCSIG__` with similar functionality. Leveraging the robust compile-time evaluation capabilities introduced in +C++20, we can implement a basic reflection library by parsing the output of these macros. #### Creating a type fingerprint -The `meta::fingerprint` class stores compile-time information about a type, including both the raw and friendly names. The code below shows how to create a fingerprint which is evaluated at compile time. +The `meta::fingerprint` class stores compile-time information about a type, including both the raw and friendly names. +The code below shows how to create a fingerprint which is evaluated at compile time. ```c++ #include @@ -379,10 +425,13 @@ constexpr essence::meta::fingerprint foo_metadata{std::type_identity{}}; spdlog::info(U8("The type name is {} and the friendly name is {}."), foo_metadata.name(), foo_metadata.friendly_name()); ``` -The implementation contains predefined friendly names of all arithmetic types as well as other built-in types like `char`, `char8_t`, `char16_t`, `char32_t`, `std::byte` and `bool`. Additionally, container types such as `std::basic_string`(with `T` = `char`, `char8_t`, `char16_t`, `char32_t`) and `std::vector` also have specialized friendly names by default. +The implementation contains predefined friendly names of all arithmetic types as well as other built-in types like +`char`, `char8_t`, `char16_t`, `char32_t`, `std::byte` and `bool`. Additionally, container types such as +`std::basic_string`(with `T` = `char`, `char8_t`, `char16_t`, `char32_t`) and `std::vector` also have specialized +friendly names by default. | Type | Friendly Name | -| ----------------------------- | ---------------------------- | +|-------------------------------|------------------------------| | `std::int8_t` | `int8` | | `std::int16_t` | `int16` | | `std::int32_t` | `int32` | @@ -412,7 +461,11 @@ More built-in types especially container types may be added in subsequent versio #### Usage of `meta::literal_string` -The `meta::literal_string` is a `struct` template satisfying the [`LiteralType`](https://en.cppreference.com/w/cpp/named_req/LiteralType) named requirement (C++20), that can be evaluated in a constexpr context such as non-type template arguments. It allows you to store a string literal at compile time, so partial code of the reflection module contains interfaces that use `meta::literal_string` as return values. Here’s an example to illustrate how such a `struct` template could be used: +The `meta::literal_string` is a `struct` template satisfying the [ +`LiteralType`](https://en.cppreference.com/w/cpp/named_req/LiteralType) named requirement (C++20), that can be evaluated +in a constexpr context such as non-type template arguments. It allows you to store a string literal at compile time, so +partial code of the reflection module contains interfaces that use `meta::literal_string` as return values. Here’s an +example to illustrate how such a `struct` template could be used: ```c++ #include @@ -435,7 +488,8 @@ struct some_class_with_literal_string{ const some_class_with_literal_string obj; ``` -`meta::literal_string` provides iteration function pairs `begin` and `end` and therefore all STL algorithms can be applied to any instances of it. +`meta::literal_string` provides iteration function pairs `begin` and `end` and therefore all STL algorithms can be +applied to any instances of it. ```c++ #include @@ -454,7 +508,8 @@ std::ranges::copy(str, std::back_inserter(chars)); #### Converting booleans to/from strings -Several utility functions are available to facilitate the conversion of boolean values to and from string representations, such as the literals `"true"` and `"false"`. +Several utility functions are available to facilitate the conversion of boolean values to and from string +representations, such as the literals `"true"` and `"false"`. ```c++ #include @@ -473,7 +528,11 @@ spdlog::info(U8("The boolean value {} has been converted to string '{}'."), emr: #### Parsing enumeration names to/from strings -In production scenarios, it is common to retrieve the text representation of an enumeration name or parse a string to obtain the corresponding enumeration value. Although C++ lacks built-in reflection capabilities, we can determine the range of an enumeration type and use the internal `meta::get_literal_string_v` function to convert each enumeration value into its string representation. By default, the range is set to [−64, 64], which is broad enough to cover most typical use cases. +In production scenarios, it is common to retrieve the text representation of an enumeration name or parse a string to +obtain the corresponding enumeration value. Although C++ lacks built-in reflection capabilities, we can determine the +range of an enumeration type and use the internal `meta::get_literal_string_v` function to convert each enumeration +value into its string representation. By default, the range is set to [−64, 64], which is broad enough to cover most +typical use cases. ```c++ template @@ -482,7 +541,8 @@ consteval auto get_enum_searching_range() noexcept { }; ``` -You can customize the range for a specific enumeration type by overloading the `meta::get_enum_searching_range` function template. +You can customize the range for a specific enumeration type by overloading the `meta::get_enum_searching_range` function +template. ```c++ #include @@ -526,7 +586,11 @@ if (auto enum_value = emr::from_string(U8("alpha_centauri"))) { } ``` -The `meta::runtime::from_string` function template is designed to be flexible with naming conventions. This means it can handle multiple naming styles and still produce the same result. For instance, if you have an enumeration or variable name in `PascalCase`, the function can correctly interpret names written in other common formats like `snake_case` or `camelCase`. This allows for greater flexibility when processing strings, making it easier to work with various naming conventions without worrying about case sensitivity or specific formatting. +The `meta::runtime::from_string` function template is designed to be flexible with naming conventions. This means it can +handle multiple naming styles and still produce the same result. For instance, if you have an enumeration or variable +name in `PascalCase`, the function can correctly interpret names written in other common formats like `snake_case` or +`camelCase`. This allows for greater flexibility when processing strings, making it easier to work with various naming +conventions without worrying about case sensitivity or specific formatting. ```c++ #include @@ -549,7 +613,12 @@ spdlog::info(emr::to_string(static_cast(emr::from_string(U8 #### Enumerating non-static data members of a structure -The `meta::runtime::enumerate_data_members` function provides a way to enumerate the public non-static data members of a `struct`. The core implementation relies on the [`Structured Binding`](https://en.cppreference.com/w/cpp/language/structured_binding) feature introduced in C++17, which enables the binding of `struct` members to variables in a single expression. By combining `Structured Binding` with the name-fetching mechanism described earlier, we can obtain name-reference pairs in the final results. Here is an example illustrating how to use this function: +The `meta::runtime::enumerate_data_members` function provides a way to enumerate the public non-static data members of a +`struct`. The core implementation relies on the [ +`Structured Binding`](https://en.cppreference.com/w/cpp/language/structured_binding) feature introduced in C++17, which +enables the binding of `struct` members to variables in a single expression. By combining `Structured Binding` with the +name-fetching mechanism described earlier, we can obtain name-reference pairs in the final results. Here is an example +illustrating how to use this function: ```cpp #include @@ -576,11 +645,15 @@ meta::runtime::enumerate_data_members(entity, [](const auto&... members) { }); ``` -The type of `arg.name` shown above is `meta::literal_string` that can be implicitly converted to `std::string_view`. The `arg.reference` is a reference to the original data member. **Please note that in this implementation, the number of public non-static data members in a `struct` should not exceed 100.** +The type of `arg.name` shown above is `meta::literal_string` that can be implicitly converted to `std::string_view`. The +`arg.reference` is a reference to the original data member. **Please note that in this implementation, the number of +public non-static data members in a `struct` should not exceed 100.** #### Enumerating enumeration names -Similar to `meta::runtime::enumerate_data_members`, the `meta::runtime::get_enum_names` and `meta::runtime::get_enum_names_only` functions are designed to retrieve the names of an enumeration. The difference between them is illustrated below: +Similar to `meta::runtime::enumerate_data_members`, the `meta::runtime::get_enum_names` and +`meta::runtime::get_enum_names_only` functions are designed to retrieve the names of an enumeration. The difference +between them is illustrated below: ```C++ #include @@ -606,22 +679,26 @@ for (auto&& [name, value] : emr::get_enum_names()) { spdlog::info(U8("{} = {}"), name, static_cast>(value)); } ``` -Also, the range of an enumeration is decided by the `meta::get_enum_searching_range` function described above. - +Also, the range of an enumeration is decided by the `meta::get_enum_searching_range` function described above. ### 👉Macro-free JSON Serialization/Deserialization #### Extensions of `nlohmann::json` -JSON serialization and deserialization are implemented directly using the reflection support within this library, which enables efficient data member extraction instead of the original macro-based methodology within `nlohmann::json`. The header file `` defines `essence::json` with a custom JSON serializer provided by the `meta::runtime::json_serializer` class. The custom serializer is able to reflect the data members of a `struct` and convert the value to or from a JSON value fast. +JSON serialization and deserialization are implemented directly using the reflection support within this library, which +enables efficient data member extraction instead of the original macro-based methodology within `nlohmann::json`. The +header file `` defines `essence::json` with a custom JSON serializer provided by the +`meta::runtime::json_serializer` class. The custom serializer is able to reflect the data members of a `struct` and +convert the value to or from a JSON value fast. ```c++ using json = nlohmann::basic_json; ``` -In addition, the header file includes the concept `essence::json_serializable`, which allows users to check if a `struct` can be serialized by `meta::runtime::json_serializer`. +In addition, the header file includes the concept `essence::json_serializable`, which allows users to check if a +`struct` can be serialized by `meta::runtime::json_serializer`. ```c++ #include @@ -633,7 +710,8 @@ if constexpr(essence::json_serializable) { } ``` -To use the features of this version of JSON class, you simply need to manipulate the JSON value as you would with the regular `nlohmann::json`. Below is an example code: +To use the features of this version of JSON class, you simply need to manipulate the JSON value as you would with the +regular `nlohmann::json`. Below is an example code: ```c++ #include @@ -650,19 +728,25 @@ spdlog::info(json.dump(4)); #### Recapping `meta::runtime::json_serializer` -The default `meta::runtime::json_serializer` class supports serialization and deserialization from arithmetic types, `bool`, enumerations, `std::vector`, `std::map`, `std::optional`, `std::basic_string` and `struct` types with public non-static data members. The list below reveals how C++ types are mapped to their corresponding JSON values. +The default `meta::runtime::json_serializer` class supports serialization and deserialization from arithmetic types, +`bool`, enumerations, `std::vector`, `std::map`, `std::optional`, +`std::basic_string` and `struct` types with public non-static data members. The list below +reveals how C++ types are mapped to their corresponding JSON values. -| C++ Type | JSON Value | -| ------------------------------------------------------------ | --------------- | -| Arithmetic types `std::int**_t`, `std::uint**_t`, `float`, `double` | `Number` | -| `bool` | `true`, `false` | -| `std::nullptr_t`, `std::nullopt_t`, `std::optional` (with an empty state) | `null` | +| C++ Type | JSON Value | +|-------------------------------------------------------------------------------------------------|-----------------| +| Arithmetic types `std::int**_t`, `std::uint**_t`, `float`, `double` | `Number` | +| `bool` | `true`, `false` | +| `std::nullptr_t`, `std::nullopt_t`, `std::optional` (with an empty state) | `null` | | `struct` types (satisfying `essence::json_serializable`), `std::optional` (that has a value) | `object` | -| `std::vector` | `array` of `T` | -| `std::map` | `object` | -| `std::basic_string` | `string` | +| `std::vector` | `array` of `T` | +| `std::map` | `object` | +| `std::basic_string` | `string` | -This implementation allows users to manually control the naming convention used during serialization and deserialization. The `meta::runtime::json_serializer` will check if a `json_serialization` enumeration is defined within a `struct` type. Currently, `snake_case`, `camelCase`, and `PascalCase` naming conventions are supported. The following code demonstrates how to define this nested enumeration: +This implementation allows users to manually control the naming convention used during serialization and +deserialization. The `meta::runtime::json_serializer` will check if a `json_serialization` enumeration is defined within +a `struct` type. Currently, `snake_case`, `camelCase`, and `PascalCase` naming conventions are supported. The following +code demonstrates how to define this nested enumeration: ```c++ struct entity { @@ -678,7 +762,9 @@ struct record { }; ``` -By default, an enumeration value is serialized as a JSON number, and vice versa. To enable conversion of an enumeration to its string representation, you need to add an `enum_to_string` member to the `json_serialization` enumeration described above. +By default, an enumeration value is serialized as a JSON number, and vice versa. To enable conversion of an enumeration +to its string representation, you need to add an `enum_to_string` member to the `json_serialization` enumeration +described above. ```c++ struct entity { @@ -779,13 +865,13 @@ auto entity = json.get(); spdlog::info(json(entity).dump(4)); ``` - - ### 👉Command-Line Parser Compatible with GNU/Linux Bash #### Conventions of `getopt` on GNU/Linux -The `getopt` command in GNU/Linux is used for parsing command-line arguments in scripts. It allows you to define short and long options and then extract the arguments provided to them by the user. Here is the typical contract for the `getopt` command: +The `getopt` command in GNU/Linux is used for parsing command-line arguments in scripts. It allows you to define short +and long options and then extract the arguments provided to them by the user. Here is the typical contract for the +`getopt` command: - Short Switches: `-s` - Short Options with Values: `-l short,options`, `-l=short,options` @@ -870,11 +956,10 @@ int main(){ } ``` - - ## Acknowledgements -This library includes several third-party submodules, each of which is exceptional and has garnered many stars on GitHub. +This library includes several third-party submodules, each of which is exceptional and has garnered many stars on +GitHub. ![](https://avatars.githubusercontent.com/u/159488?s=48&v=4)[nlohmann/json: JSON for Modern C++](https://github.com/nlohmann/json)