{"id":22646920,"url":"https://github.com/refvalue/cpp-essence","last_synced_at":"2025-07-01T01:34:44.044Z","repository":{"id":262441422,"uuid":"860182516","full_name":"refvalue/cpp-essence","owner":"refvalue","description":"A lightweight C++ utility library offering essential tools like reflection, serialization, REST networking, encryption, chunk processing, multilingual support, formatting, template metaprogramming, and command line parsing.","archived":false,"fork":false,"pushed_at":"2025-03-10T13:21:18.000Z","size":1417,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T06:47:16.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://i.refvalue.org/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/refvalue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-20T01:17:57.000Z","updated_at":"2024-11-29T01:19:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"cf590c0a-a069-4299-8ff9-fd53a9468602","html_url":"https://github.com/refvalue/cpp-essence","commit_stats":null,"previous_names":["refvalue/cpp-essence"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/refvalue/cpp-essence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refvalue%2Fcpp-essence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refvalue%2Fcpp-essence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refvalue%2Fcpp-essence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refvalue%2Fcpp-essence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/refvalue","download_url":"https://codeload.github.com/refvalue/cpp-essence/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/refvalue%2Fcpp-essence/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262879490,"owners_count":23378624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-09T07:31:09.553Z","updated_at":"2025-07-01T01:34:44.013Z","avatar_url":"https://github.com/refvalue.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 😀CPP Essence -- Modern C++ Utility Library\n\n\n\n[![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) [![Coverage Status](https://coveralls.io/repos/github/refvalue/cpp-essence/badge.svg)](https://coveralls.io/github/refvalue/cpp-essence)\n\n\n\n![](assets/header.gif)\n\n\n\n## ℹA NEW RELEASE COMING SOON!\n\nThis open-source project is currently under development, with the author focusing on completing and improving unit tests to ensure code correctness. Please note that this README is unstable and may change at any time until the first version is released. I really appreciate your contributions through GitHub issues in this area. \n\n❤Consider forking this repo or upstream if you like this project! Big thanks!\n\n\n\n## 📚Requirements\n\n- MSVC \u003e= 14.30 (Visual Studio 2022 17.0)\n- GCC \u003e= 11.2\n- Clang \u003e= 17.0 (Supporting [P1816R0 Class Template Argument Deduction for Aggregates](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1816r0.pdf))\n- Emscripten \u003e= 3.1.52\n- Host GLIBC \u003e= 2.31 (When compiling on Linux)\n- C++ 20 Support\n- JDK \u003e= 8 (Optional if `ES_WITH_JNI` = `OFF`)\n\n\n\n## 📂[Document \u0026 API Reference](https://docs.refvalue.org/cppessence/)\n\n\n\n## 💻Importing the Prebuilt Package with CMake\n\n### Step-by-step Configuration\n\nTo use this library on your target platform immediately, you can download the prebuilt packages from\nthe [Release](http://www.baidu.com) page. After obtaining the compressed files, such as\n`cpp-essence-1.0-windows-x86_64-release.zip` and `cpp-essence-1.0-linux-x86_64.tgz`, you can decompress them to any\nlocation on your disk.\n\n```powershell\nExpand-Archive -Path './cpp-essence-0.1.0-windows-amd64-release.zip' -DestinationPath 'C:\\path\\to\\extract\\folder'\n```\n\n```bash\ntar -zxf ./cpp-essence-0.1.0-linux-amd64.tgz\n```\n\nThen you need to modify the `CMakeUserPresets.json` file in your own project to add a CMake variable which stores the\npath of the directory that the file was decompressed to. Here is an example:\n\n```json\n{\n  \"version\": 3,\n  \"configurePresets\": [\n    {\n      \"name\": \"windows-debug-user\",\n      \"inherits\": \"windows-debug\",\n      \"cacheVariables\": {\n        \"ES_CPP_ESSENCE_ROOT\": \"E:/Libs/cpp-essence-0.1.0-windows-amd64-debug\"\n      }\n    },\n    {\n      \"name\": \"windows-release-user\",\n      \"inherits\": \"windows-release\",\n      \"cacheVariables\": {\n        \"ES_CPP_ESSENCE_ROOT\": \"E:/Libs/cpp-essence-0.1.0-windows-amd64-release\"\n      }\n    },\n    {\n      \"name\": \"linux-release-user\",\n      \"inherits\": \"linux-release\",\n      \"cacheVariables\": {\n        \"ES_CPP_ESSENCE_ROOT\": \"/opt/cpp-essence-0.1.0-linux-amd64\"\n      }\n    }\n  ]\n}\n```\n\nThen you can add the following code to your CMake script file, such as `Dependencies.cmake` for dependency management:\n\n```cmake\nfind_package(CppEssence REQUIRED HINTS ${ES_CPP_ESSENCE_ROOT})\n```\n\nThe final step is to link the found package to your target as demonstrated in the example below:\n\n```cmake\ntarget_link_libraries(your_target_name PRIVATE CppEssence::cpp-essence) # The mandatory package.\ntarget_link_libraries(your_target_name PRIVATE CppEssenceJniSupport::cpp-essence-jni-support) # Optional JNI utilities.\n```\n\n### Release or Debug Version\n\nDue to the different ABIs between the Release and Debug versions of Microsoft's STL, Windows DLLs that export any STL\nsymbols cannot be mixed. Forcing this will result in severe issues, such as program crashes or unstable running states.\nTo avoid this problem, it is highly recommended to ensure that your DLL has the same build type as this library.\n\nThere is no such issue on Linux/Unix platform, so only the Release version is provided on\nthe [Release](http://www.baidu.com) page.\n\n\n\n## 💡Main Features\n\n### 1. Reflection Tool Library\n\n- **100% Macro-Free Design**: Implemented using native C++ with no reliance on macros.\n- **Data Member Traversal**: Supports direct traversal of class data members, allowing easy access to all member\n  variables.\n- **Member Name Retrieval**: Automatically retrieves the names of class members.\n- **Enum Support**: Provides automatic enum-to-string conversion and the ability to read enum ranges.\n- **JSON Serialization**: Supports automatic serialization and deserialization of class objects to/from JSON.\n\n### 2. Command Line Tool Library\n\n- **GNU/Linux Bash Compliance**: Supports multiple command-line parameter formats, including:\n    - `--name=value`, `-n=value`, `--name value`, `-n value`, `--switch`, `-s`\n    - `--values 1,2,3,4,5`, `-v 1,2,3,4,5`, `--values alice,bob,paul`, `-v alice,bob,paul`\n    - `-abcde` and many more combinations.\n- **Array \u0026 Enum Parsing**: Supports parsing of array and enum values, with automatic conversion to data models using\n  reflection.\n\n### 3. Internationalization Support\n\n- **Multi-language Mapping**: Allows the creation of multi-language mapping files, which can be compiled into a compact\n  binary format.\n- **Dynamic Language Switching**: Supports runtime switching of languages and fetching of language-specific texts.\n- **Independent Language Packs**: Supports independent language packs for modular localization without interference.\n\n### 4. Multicast Delegate System\n\n- **Multicast Delegate**: Implements a multi-subscription delegate system similar to C#'s `MulticastDelegate`, enabling\n  thread-safe event triggering and multiple listeners.\n\n### 5. I/O Basic Support Library\n\n- **C++23 `spanstream` Support**: Implements the C++23 `spanstream` pattern for efficient stream processing.\n- **File Type Detection**: Supports quick identification of common image types based on file headers.\n- **Abstract File System Operations**: Provides a unified interface for file system operations across platforms.\n- **Embedded Resources**: Supports embedded resources with cross-platform compatibility, based on CMRC.\n\n### 6. Networking Library\n\n- **RESTful HTTP Communication**: Supports REST-style HTTP communication.\n- **Server-Side Events**: Implements Server-Side Events (SSE) for real-time server-client communication.\n- **File Download with Progress**: Supports downloading files with progress tracking.\n\n### 7. JSON Library\n\n- **nlohmann/json Integration**: Built on the popular `nlohmann json` library, with support for automatic member\n  reflection.\n- **Flexible Naming Conventions**: Supports automatic conversion between `Camel`, `Pascal`, and `Snake` case styles.\n\n### 8. Cryptography Library\n\n- **Symmetric \u0026 Asymmetric Encryption**: Supports common cryptographic algorithms, including AES, SM2, SM4, RSA, and\n  elliptic curve cryptography.\n- **Block-Level Encryption**: Provides support for block encryption and decryption for large data.\n\n### 9. Logging System\n\n- **spdlog Integration**: Built on the popular `spdlog` library, with support for logging, log dumping, and log\n  rotation.\n- **Internationalization Support**: Allows logging messages in multiple languages.\n\n### 10. Data Hashing\n\n- **Multiple Hashing Algorithms**: Supports SHA1, SHA2, SHA3, MD5, SM3, and more.\n- **Large File Checksums**: Supports checksum calculation for large files with chunk-based hashing.\n\n### 11. JNI Support Library(Optional)\n\n- **Automatic Data Mapping**: Provides automatic mapping of C++ containers and native types to JNI types.\n- **Custom Java Class Conversion**: Supports custom data conversion rules for Java class types.\n- **Managed Object Lifecycle**: Allows control over the lifecycle of managed objects in JNI.\n\n### 12. Functional Programming Library\n\n- **Convenient Templates**: Provides functional programming utilities, including function signature reflection and\n  easy-to-use function objects.\n- **Concepts Support**: Includes helpful concepts for functional programming in C++.\n\n### 13. Native API Programming Library\n\n- **Handle Management**: Provides RTTI-based management of raw and managed API handles.\n- **Custom System Handle Management**: Allows user-defined management of native API calls and handle lifecycle to avoid\n  memory leaks.\n\n### 14. Hash Utilities\n\n- **Unified Hashing Methods**: Offers unified methods for combining hash values.\n- **Case-Insensitive String Comparisons**: Supports case-insensitive string comparisons and dictionary-based string\n  lookups.\n\n### 15. Formatting Library\n\n- **fmt Library Support**: Built on the popular `fmt` library, offering flexible string formatting options.\n- **C++20 `format`**: Dynamically wraps the `std::format` library depending on the user's environment.\n\n### 16. String Library\n\n- **Zero-Terminated Strings**: Supports `zstring_view`, a string view type for efficiently passing C-style\n  null-terminated strings.\n- **C-Style String Support**: Optimized for interop with lower-level C APIs.\n\n### 17. Ranges Adaptation Library\n\n- **C++20 Range Extensions**: Extends C++20 `Ranges` with additional utilities like `join_with` for advanced use cases.\n- **Comprehensive Functionality**: Enhances the business logic with extended range-based operations.\n\n### 18. ABI Compatibility Library\n\n- **ABI Compatibility**: Facilitates ABI-compatible programming for common types like `vector`, `map`, `list`, `string`,\n  etc.\n- **JSON Support**: Adds seamless integration for JSON data manipulation.\n\n### 19. Graphics Support Library\n\n- **Color Space Support**: Supports ARGB and YUV color spaces, with over a hundred built-in color values.\n- **Automatic Type Conversion**: Supports automatic conversion between different graphics types.\n\n### 20. Character Encoding Library\n\n- **UTF-8, UTF-16, and Native Encoding**: Supports conversion between UTF-8, UTF-16, and native encodings (`char` or\n  `wchar_t`).\n- **Comprehensive String Operations**: Provides a wide range of string handling functions.\n\n### 21. Numeric Conversion Library\n\n- **String Conversion**: Provides convenient `from_string` and `to_string` utilities for seamless conversion between\n  various data types and strings.\n\n### 22. Compression Library\n\n- **ZSTD, ZIP, and GZIP**: Supports ZSTD, ZIP, and GZIP compression algorithms for efficient data compression and\n  decompression.\n\n\n\n## 🙋Quick Samples\n\n### 👉[P1423R3](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html) char8_t Backward Compatibility Remediation\n\n#### Compatibility between `char8_t` and `char`\n\nIn C++20, the introduction of the new built-in character type `char8_t` and the `std::u8string` (which is essentially\n`std::basic_string\u003cchar8_t\u003e`) was meant to provide a better and more standardized way to handle UTF-8 encoded\ncharacters. However, the decision to **ban implicit conversions between `char8_t` and `char`** has introduced some\nchallenges for developers, especially when migrating legacy code that was designed around `std::string` (which uses\n`char`) and `std::string_view`.\n\n```cpp\n#include \u003cstring\u003e\n#include \u003cstring_view\u003e\n\nstd::u8string u8str = u8\"UTF-8 text\";\nstd::u8string_view u8strv = u8str;\nstd::string str = u8str; // Ill-formed.\nstd::string_view strv = u8str; // Ill-formed.\nstd::string_view strv2 = u8strv; // Ill-formed.\n```\n\n#### Proposal P1423R3\n\nThe proposal **P1423R3** introduces a methodology to handle the compatibility problem caused by the introduction of\n`char8_t` in C++20, particularly regarding the migration of legacy code. It suggests that `char` and `std::string`\nshould be used universally where possible, avoiding the direct use of `char8_t` and `std::u8string` in most cases. This\napproach aims to ensure that existing libraries and interfaces that rely on `std::string` can continue to function\nwithout modification or the need for explicit casting between `char` and `char8_t`.\n\nThe macro `U8` represents a UTF-8 encoded string literal within this implementation of **P1423R3**. Here’s a simple code\nblock demonstrating how this compatibility could be managed:\n\n```cpp\n#include \u003carray\u003e\n#include \u003cstring\u003e\n#include \u003cstring_view\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n\nconstexpr char u8char = U8('A');\n\nconstexpr auto char_array = U8(\"This is UTF-8 encoded.\"); // const char[N]\nconstexpr std::array char_std_array = U8(\"This is UTF-8 encoded.\"); // std::array\u003cchar, N\u003e\nconst std::string str = U8(\"Here's some text in UTF-8.\"); // Well-formed.\nconst std::string_view strv = str; // Well-formed.\n\nconstexpr auto raw_literal = U8(R\"(C:\\Windows\\System32)\");\n\n// Interop between std::string and std::u8string.\nconst std::u8string u8str = essence::to_u8string(strv);\nconst std::string strconv = essence::from_u8string(u8str);\n```\n\n#### Portable approach to construct `std::filesystem::path` with UTF-8\n\nThe `std::filesystem::path` introduced by the C++17 Standard defines one constructor which has a signature as follows:\n\n```cpp\ntemplate\u003ctypename Source\u003e\nstd::filesystem::path::path(const Source\u0026 source, std::filesystem::path::format fmt = std::filesystem::path::auto_format);\n```\n\nAny of the character types `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t` is allowed for the type parameter\n`Source`. To designate a UTF-8 encoded string precisely, you can call `essence::to_u8string` to convert your\n`std::string` to `std::u8string` to enable the `char8_t` overload.\n\n```cpp\n#include \u003cfilesystem\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n\nconst std::filesystem::path path{essence::to_u8string(U8(\"/usr/local/etc\"))}; // Ensures UTF-8.\n```\n\n### 👉Globalization with Dynamic Language Switching\n\nTo enable multi-language support, you can create the directory structure and files below.\n\n1. **Create the `lang` directory**: This will be the main directory that holds language-specific JSON files.\n2. **Create `en-US.json` and `zh-CN.json`**: These files will contain the language-specific text mappings.\n3. **Create `CMakeLists.txt`**: This file will include instructions for building the project, especially if you want to\n   handle the language files in the build process.\n\nHere is how the directory structure should look:\n\n```\n|-- lang/\n|   |-- en-US.json\n|   |-- zh-CN.json\n|   |-- CMakeLists.txt\n```\n\nThe  `en-US.json` contains keyword mappings written in American English.\n\n```json\n{\n  \"hello world\": \"hello world\",\n  \"file not found\": \"The file was not found.\",\n  \"illegal pattern\": \"The regex pattern was illegal.\"\n}\n```\n\nThe `zh-CN.json` contains keyword mapping written in Chinese Mandarin.\n\n```json\n{\n  \"hello world\": \"你好世界\",\n  \"file not found\": \"文件未找到。\",\n  \"illegal pattern\": \"正则表达式规则无效。\"\n}\n```\n\nThe `CMakeLists.txt` describes the language resources.\n\n```cmake\ninclude(ESLangCompiler)\n\nes_add_lang_resources(\n    my-test # The target that the language resources will be attached to.\n    NAME my_test # The suffix of the automatically generated header file：user_globalization_my_test.hpp。\n    ROOT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} # The root directory of the language JSON files.\n    NAMESPACE essence::misctest::lang # The namespace of the generated header file.\n)\n```\n\nTo enable globalization integration, you need to rebuild the CMake cache and then the generated header will be\navailable.\n\n```cpp\n#include \"user_globalization_my_test.hpp\"\n\n#include \u003cessence/abi/string.hpp\u003e\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/format_remediation.hpp\u003e\n#include \u003cessence/spdlog_extension.hpp\u003e\n\nint main() {\n    using namespace essence;\n    using misctest::lang::get_bounded_locale;\n    \n    // Switches to zh-CN.\n    misctest::lang::get_bounded_translator().set_language(U8(\"zh-CN\"));\n    \n    // Examples of spdlog::ginfo, spdlog::gwarn, spdlog::gerror, spdlog::gtrace\n    // to support globalized text logging.\n    spdlog::ginfo(get_bounded_locale(), U8(\"hello world\"));\n    spdlog::ginfo(get_bounded_locale(), U8(\"file not found\"));\n    spdlog::ginfo(get_bounded_locale(), U8(\"illegal pattern\"));\n    \n    // Uses gformat, gformat_as to support globalized text formatting.\n    auto str1 = gformat(get_bounded_locale(), U8(\"hello world = {}\"), U8(\"hello world\"));\n    auto str2 = gformat(get_bounded_locale(), U8(\"file not found = {}\"), U8(\"file not found\"));\n    auto str3 = gformat(get_bounded_locale(), U8(\"illegal pattern = {}\"), U8(\"illegal pattern\"));\n    \n    // Uses custom std::basic_string\u003c\u003e as a return value.\n    // Here abi::string is an ABI-compatible string, referring to the ABI-compatible types.\n    auto abi_str1 = gformat_as\u003cabi::string\u003e(get_bounded_locale(), U8(\"hello world = {}\"), U8(\"hello world\"));\n    auto abi_str2 = gformat_as\u003cabi::string\u003e(get_bounded_locale(), U8(\"file not found = {}\"), U8(\"file not found\"));\n    auto abi_str3 = gformat_as\u003cabi::string\u003e(get_bounded_locale(), U8(\"illegal pattern = {}\"), U8(\"illegal pattern\"));\n    \n    // Ordinary logging outputs.\n    spdlog::info(str1);\n    spdlog::info(str2);\n    spdlog::info(str3);\n    \n    spdlog::info(abi_str1);\n    spdlog::info(abi_str2);\n    spdlog::info(abi_str3);\n}\n```\n\n### 👉Reflecting Classes and Enumerations\n\nAll runtime reflection functions are located in `\u003cessence/meta/runtime/*.hpp\u003e`.\n\nAll compile-time reflection features can be found in `\u003cessence/meta/*.hpp\u003e`.\n\n#### Background\n\nThe C++ Reflection Proposal has not yet been accepted into the standard. However, in modern C++ compilers, there are\nsome \"magic\" macros that can be evaluated dynamically within a functional context. For example, GCC provides\n`__PRETTY_FUNCTION__`, which returns a literal string of the enclosing function's signature, while MSVC offers\n`__FUNCSIG__` with similar functionality. Leveraging the robust compile-time evaluation capabilities introduced in\nC++20, we can implement a basic reflection library by parsing the output of these macros.\n\n#### Creating a type fingerprint\n\nThe `meta::fingerprint` class stores compile-time information about a type, including both the raw and friendly names.\nThe code below shows how to create a fingerprint which is evaluated at compile time.\n\n```cpp\n#include \u003ctype_traits\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/fingerprint.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nstruct foo{};\n\nconstexpr essence::meta::fingerprint foo_metadata{std::type_identity\u003cfoo\u003e{}};\n\nspdlog::info(U8(\"The type name is {} and the friendly name is {}.\"), foo_metadata.name(), foo_metadata.friendly_name());\n```\n\nThe implementation contains predefined friendly names of all arithmetic types as well as other built-in types like\n`char`, `char8_t`, `char16_t`, `char32_t`, `std::byte` and `bool`. Additionally, container types such as\n`std::basic_string\u003cT\u003e`(with `T` = `char`, `char8_t`, `char16_t`, `char32_t`) and  `std::vector\u003cT\u003e` also have specialized\nfriendly names by default.\n\n| Type                          | Friendly Name                |\n|-------------------------------|------------------------------|\n| `std::int8_t`                 | `int8`                       |\n| `std::int16_t`                | `int16`                      |\n| `std::int32_t`                | `int32`                      |\n| `std::int64_t`                | `int64`                      |\n| `std::uint8_t`                | `uint8`                      |\n| `std::uint16_t`               | `uint16`                     |\n| `std::uint32_t`               | `uint32`                     |\n| `std::uint64_t`               | `uint64`                     |\n| `float`                       | `float`                      |\n| `double`                      | `double`                     |\n| `long double`                 | `long double`                |\n| `bool`                        | `boolean`                    |\n| `std::byte`                   | `byte`                       |\n| `char`                        | `char`                       |\n| `wchar_t`                     | `wchar`                      |\n| `char8_t`                     | `u8char`                     |\n| `char16_t`                    | `u16char`                    |\n| `char32_t`                    | `u32char`                    |\n| `std::basic_string\u003cchar\u003e`     | `string`                     |\n| `std::basic_string\u003cwchar_t\u003e`  | `wstring`                    |\n| `std::basic_string\u003cchar8_t\u003e`  | `u8string`                   |\n| `std::basic_string\u003cchar16_t\u003e` | `u16string`                  |\n| `std::basic_string\u003cchar32_t\u003e` | `u32string`                  |\n| `std::vector\u003cT\u003e`              | `vector\u003cfriendly name of T\u003e` |\n\nMore built-in types especially container types may be added in subsequent versions.\n\n#### Usage of `meta::literal_string`\n\nThe `meta::literal_string` is a `struct` template satisfying the [\n`LiteralType`](https://en.cppreference.com/w/cpp/named_req/LiteralType) named requirement (C++20), that can be evaluated\nin a constexpr context such as non-type template arguments. It allows you to store a string literal at compile time, so\npartial code of the reflection module contains interfaces that use `meta::literal_string` as return values. Here’s an\nexample to illustrate how such a `struct` template could be used:\n\n```cpp\n#include \u003cstring_view\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/literal_string.hpp\u003e\n\nusing essence::meta::literal_string;\n\nconstexpr literal_string str{U8(\"Constexpr String Here\")};\nconstexpr std::string_view strv{str}; // Implicit conversion to std::string_view.\nconstexpr const char* strp = str.c_str(); // Gets the underlying pointer.\nconstexpr bool equal = str == str;\n\ntemplate\u003cliteral_string S\u003e\nstruct some_class_with_literal_string{\n    static constexpr std::string_view str{S};\n};\n\nconst some_class_with_literal_string\u003cU8(\"Non-type Arg\")\u003e obj;\n```\n\n`meta::literal_string` provides iteration function pairs `begin` and `end` and therefore all STL algorithms can be\napplied to any instances of it.\n\n```cpp\n#include \u003calgorithm\u003e\n#include \u003cvector\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/literal_string.hpp\u003e\n\nusing essence::meta::literal_string;\n\nconstexpr literal_string str{U8(\"Hello World\")};\nstd::vector\u003cchar\u003e chars;\n\nstd::ranges::copy(str, std::back_inserter(chars));\n```\n\n#### Converting booleans to/from strings\n\nSeveral utility functions are available to facilitate the conversion of boolean values to and from string\nrepresentations, such as the literals `\"true\"` and `\"false\"`.\n\n```cpp\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/boolean.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nnamespace emr = essence::meta::runtime;\n\nif (auto bool_value = emr::from_string\u003cbool\u003e(U8(\"true\"))) {\n    spdlog::info(U8(\"The string 'true' has been parsed into boolean value {}.\"), *bool_value);\n}\n    \nspdlog::info(U8(\"The boolean value {} has been converted to string '{}'.\"), emr::to_string(false));\n```\n\n#### Parsing enumeration names to/from strings\n\nIn production scenarios, it is common to retrieve the text representation of an enumeration name or parse a string to\nobtain the corresponding enumeration value. Although C++ lacks built-in reflection capabilities, we can determine the\nrange of an enumeration type and use the internal `meta::get_literal_string_v` function to convert each enumeration\nvalue into its string representation. By default, the range is set to [−64, 64], which is broad enough to cover most\ntypical use cases.\n\n```cpp\ntemplate \u003ctypename T\u003e\nconsteval auto get_enum_searching_range() noexcept {\n    return std::pair\u003cstd::int64_t, std::int64_t\u003e{-64, 64};\n};\n```\n\nYou can customize the range for a specific enumeration type by overloading the `meta::get_enum_searching_range` function\ntemplate.\n\n```cpp\n#include \u003cconcepts\u003e\n#include \u003cutility\u003e\n\n#include \u003cessence/meta/enum.hpp\u003e\n\nenum class my_kind {\n    boy = 100,\n    girl = 105,\n    other = 109,\n};\n\nnamespace essence::meta {\n    template\u003cstd::same_as\u003cmy_kind\u003e\u003e\n    consteval auto get_enum_searching_range() noexcept {\n        return std::pair{100, 109};\n    }\n}\n```\n\nThe following code demonstrates how to implement conversions between strings and enumeration names:\n\n```cpp\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/runtime/enum.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nnamespace emr = essence::meta::runtime;\n\nenum class star_type {\n    sun,\n    alpha_centauri,\n    sirius,\n};\n\n// The from_string\u003cT\u003e function returns a std::optional\u003cT\u003e.\nif (auto enum_value = emr::from_string\u003cstar_type\u003e(U8(\"alpha_centauri\"))) {\n    spdlog::info(U8(\"The parsed enumeration is {}.\"), emr::to_string(*enum_value));\n}\n```\n\nThe `meta::runtime::from_string` function template is designed to be flexible with naming conventions. This means it can\nhandle multiple naming styles and still produce the same result. For instance, if you have an enumeration or variable\nname in `PascalCase`, the function can correctly interpret names written in other common formats like `snake_case` or\n`camelCase`. This allows for greater flexibility when processing strings, making it easier to work with various naming\nconventions without worrying about case sensitivity or specific formatting.\n\n```cpp\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/runtime/boolean.hpp\u003e\n#include \u003cessence/meta/runtime/enum.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nenum class language_type {\n    american_english,\n    british_english,\n};\n\nnamespace emr = essence::meta::runtime;\n\nspdlog::info(emr::to_string(static_cast\u003cbool\u003e(emr::from_string\u003clanguage_type\u003e(U8(\"american_english\"))))); // Outputs 'true'.\nspdlog::info(emr::to_string(static_cast\u003cbool\u003e(emr::from_string\u003clanguage_type\u003e(U8(\"americanEnglish\"))))); // Outputs 'true'.\nspdlog::info(emr::to_string(static_cast\u003cbool\u003e(emr::from_string\u003clanguage_type\u003e(U8(\"AmericanEnglish\")))); // Outputs 'true'.\n```\n\n#### Enumerating non-static data members of a structure\n\nThe `meta::runtime::enumerate_data_members` function provides a way to enumerate the public non-static data members of a\n`struct`. The core implementation relies on the [\n`Structured Binding`](https://en.cppreference.com/w/cpp/language/structured_binding) feature introduced in C++17, which\nenables the binding of `struct` members to variables in a single expression. By combining `Structured Binding` with the\nname-fetching mechanism described earlier, we can obtain name-reference pairs in the final results. Here is an example\nillustrating how to use this function:\n\n```cpp\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/runtime/struct.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nstruct foo {\n    int a{};\n    long b{};\n    double c{};\n};\n\nconstexpr foo entity{\n    .a = 1, \n    .b = 2,\n    .c = 3,\n};\n\nmeta::runtime::enumerate_data_members(entity, [](const auto\u0026... members) {\n    auto handler = [](const auto\u0026 arg) { spdlog::info(U8(\"{} = {}\"), arg.name, arg.reference); };\n\n    (handler(members), ...);\n});\n```\n\nThe type of `arg.name` shown above is `meta::literal_string` that can be implicitly converted to `std::string_view`. The\n`arg.reference` is a reference to the original data member. **Please note that in this implementation, the number of\npublic non-static data members in a `struct` should not exceed 100.**\n\n#### Enumerating enumeration names\n\nSimilar to `meta::runtime::enumerate_data_members`, the `meta::runtime::get_enum_names` and\n`meta::runtime::get_enum_names_only` functions are designed to retrieve the names of an enumeration. The difference\nbetween them is illustrated below:\n\n```cpp\n#include \u003ctype_traits\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/meta/runtime/enum.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nnamespace emr = essence::meta::runtime;\n\nenum class test_enum {\n    something,\n    anything,\n    everything,\n};\n\nfor (auto\u0026\u0026 item : emr::get_enum_names_only\u003ctest_enum\u003e()) {\n    spdlog::info(item);\n}\n\nfor (auto\u0026\u0026 [name, value] : emr::get_enum_names\u003ctest_enum\u003e()) {\n    spdlog::info(U8(\"{} = {}\"), name, static_cast\u003cstd::underlying_type_t\u003ctest_enum\u003e\u003e(value));\n}\n```\n\nAlso, the range of an enumeration is decided by the `meta::get_enum_searching_range` function described above.\n\n### 👉Macro-free JSON Serialization/Deserialization\n\n#### Extensions of `nlohmann::json`\n\nJSON serialization and deserialization are implemented directly using the reflection support within this library, which\nenables efficient data member extraction instead of the original macro-based methodology within `nlohmann::json`. The\nheader file `\u003cessence/json_compat.hpp\u003e` defines `essence::json` with a custom JSON serializer provided by the\n`meta::runtime::json_serializer` class. The custom serializer is able to reflect the data members of a `struct` and\nconvert the value to or from a JSON value fast.\n\n```cpp\nusing json = nlohmann::basic_json\u003cstd::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double,\n        std::allocator, meta::runtime::json_serializer\u003e;\n```\n\nIn addition, the header file includes the concept `essence::json_serializable\u003cT\u003e`, which allows users to check if a\n`struct` can be serialized by `meta::runtime::json_serializer`.\n\n```cpp\n#include \u003cstring\u003e\n\n#include \u003cessence/json_compat.hpp\u003e\n\nif constexpr(essence::json_serializable\u003cstd::string\u003e) {\n    // This condition is always true here.\n}\n```\n\nTo use the features of this version of JSON class, you simply need to manipulate the JSON value as you would with the\nregular `nlohmann::json`. Below is an example code:\n\n```cpp\n#include \u003cfstream\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/json_compat.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nauto json = essence::json::parse(std::ifstream{U8(\"/tmp/test.json\"), std::ios_base::in});\n\nspdlog::info(json.dump(4));\n```\n\n#### Recapping `meta::runtime::json_serializer`\n\nThe default `meta::runtime::json_serializer` class supports serialization and deserialization from arithmetic types,\n`bool`, enumerations, `std::vector\u003cT, Allocator\u003e`, `std::map\u003cKey, T, Compare, Allocator\u003e`, `std::optional\u003cT\u003e`,\n`std::basic_string\u003cCharT, CharTraits, Allocator\u003e` and `struct` types with public non-static data members. The list below\nreveals how C++ types are mapped to their corresponding JSON values.\n\n| C++ Type                                                                                        | JSON Value      |\n|-------------------------------------------------------------------------------------------------|-----------------|\n| Arithmetic types `std::int**_t`, `std::uint**_t`, `float`, `double`                             | `Number`        |\n| `bool`                                                                                          | `true`, `false` |\n| `std::nullptr_t`, `std::nullopt_t`, `std::optional\u003cT\u003e` (with an empty state)                    | `null`          |\n| `struct` types (satisfying `essence::json_serializable`), `std::optional\u003cT\u003e` (that has a value) | `object`        |\n| `std::vector\u003cT, Allocator\u003e`                                                                     | `array` of  `T` |\n| `std::map\u003cKey, T, Compare, Allocator\u003e`                                                          | `object`        |\n| `std::basic_string\u003cCharT, CharTraits, Allocator\u003e`                                               | `string`        |\n\nThis implementation allows users to manually control the naming convention used during serialization and\ndeserialization. The `meta::runtime::json_serializer` will check if a `json_serialization` enumeration is defined within\na `struct` type. Currently, `snake_case`, `camelCase`, and `PascalCase` naming conventions are supported. The following\ncode demonstrates how to define this nested enumeration:\n\n```cpp\nstruct entity {\n    enum class json_serialization { camel_case };\n};\n\nstruct model {\n    enum class json_serialization { pascal_case };\n};\n\nstruct record {\n    enum class json_serialization { snake_case };\n};\n```\n\nBy default, an enumeration value is serialized as a JSON number, and vice versa. To enable conversion of an enumeration\nto its string representation, you need to add an `enum_to_string` member to the `json_serialization` enumeration\ndescribed above.\n\n```cpp\nstruct entity {\n    enum class json_serialization {\n        camel_case,\n        enum_to_string,\n    };\n};\n```\n\n#### Serializing JSON to arbitrary values\n\nHere are some examples of JSON serialization including complex values:\n\n```cpp\n#include \u003cmap\u003e\n#include \u003coptional\u003e\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/json_compat.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nstruct foo {\n    int a{};\n    long b{};\n    double c{};\n};\n\nstruct entity {\n    enum class json_serialization { camel_case };\n\n    int blice_age{};\n    long bob_index_first{};\n    double john_make_living{};\n    std::optional\u003cstd::string\u003e str;\n    std::optional\u003cstd::vector\u003cfoo\u003e\u003e items;\n    std::map\u003cstd::string, std::optional\u003cfoo\u003e\u003e mapping;\n};\n\nessence::json json(entity{\n    .blice_age        = 21,\n    .bob_index_first  = 22,\n    .john_make_living = 12.34,\n    .str = std::nullopt,\n    .items = std::vector\u003cfoo\u003e{{1, 2, 3}},\n    .mapping = {\n                  {U8(\"Today\"), foo{.a = 1999}}\n               },\n});\n\nspdlog::info(json.dump(4));\n```\n\n#### Deserializing from various objects\n\nThis is some sample code that supports conversion of complex values:\n\n```cpp\n#include \u003cmap\u003e\n#include \u003coptional\u003e\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/json_compat.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nstruct foo {\n    int a{};\n    long b{};\n    double c{};\n};\n\nstruct entity {\n    enum class json_serialization { pascal_case };\n\n    int blice_age{};\n    long bob_index_first{};\n    double john_make_living{};\n    std::optional\u003cstd::string\u003e str;\n    std::optional\u003cstd::vector\u003cfoo\u003e\u003e items;\n    std::map\u003cstd::string, std::optional\u003cfoo\u003e\u003e mapping;\n};\n\nessence::json json{\n    {U8(\"BliceAge\"), 12},\n    {U8(\"BobIndexFirst\"), 13},\n    {U8(\"JohnMakeLiving\"), 67.89},\n    {U8(\"Mapping\"), {{U8(\"Tomorrow\"), essence::json(foo{.c = 101})}}},\n};\n\nauto entity = json.get\u003centity\u003e();\n\nspdlog::info(json(entity).dump(4));\n```\n\n### 👉Command-Line Parser Compatible with GNU/Linux Bash\n\n#### Conventions of `getopt` on GNU/Linux\n\nThe `getopt` command in GNU/Linux is used for parsing command-line arguments in scripts. It allows you to define short\nand long options and then extract the arguments provided to them by the user. Here is the typical contract for the\n`getopt` command:\n\n- Short Switches: `-s`\n- Short Options with Values: `-l short,options`, `-l=short,options`\n- Long Switches: `--switch`\n- Long Switches with Values: `--list short,options`, `--list=short,options`\n- Combined Short Switches: `-abc` (that is equivalent to `-a -b -c`)\n\n#### The compatible implementation: `cli::option\u003cT\u003e`\n\n```cpp\n#include \u003cstring\u003e\n#include \u003cstring_view\u003e\n#include \u003cvector\u003e\n\n#include \u003cessence/char8_t_remediation.hpp\u003e\n#include \u003cessence/cli/option.hpp\u003e\n#include \u003cessence/cli/arg_parser.hpp\u003e\n#include \u003cessence/range.hpp\u003e\n\n#include \u003cspdlog/spdlog.h\u003e\n\nnamespace {\n    enum class tex {\n        fire,\n        water,\n        bat,\n    };\n\n    struct model {\n        enum class json_serialization { camel_case };\n\n        std::string set_text;\n        bool flower{};\n        std::vector\u003ctex\u003e set_target;\n    };\n}\n\nint main(){\n    auto opt1 = cli::option\u003cstd::string\u003e{}\n                 .set_name(U8(\"set_text\"))\n                 .set_description(U8(\"Sets text\"))\n                 .add_aliases(U8(\"t\"))\n                 .set_valid_values(U8(\"a\"), U8(\"b\"), U8(\"c\"))\n                 .as_abstract();\n\n    auto opt2 = cli::option\u003cbool\u003e{}\n                 .set_name(U8(\"set_flower\"))\n                 .set_description(U8(\"Enables a flower\"))\n                 .add_aliases(U8(\"f\"))\n                 .as_abstract();\n    \n    auto opt3 = cli::option\u003cstd::vector\u003ctex\u003e\u003e{}\n                 .set_name(U8(\"set_target\"))\n                 .set_description(U8(\"Sets a target list\"))\n                 .add_aliases(U8(\"d\"))\n                 .as_abstract();\n\n    cli::arg_parser parser;\n    \n    parser.on_error([](std::string_view message) { spdlog::error(message); });\n\t\n    parser.add_option(opt1);\n    parser.add_option(opt2);\n    parser.add_option(opt3);\n\t\n    parser.parse(std::array\u003cabi::string, 6\u003e{\n        U8(\"--set_text\"), U8(\"a\"), U8(\"-f=false\"), U8(\"hahaha\"), U8(\"--set_target\"), U8(\"fire,bat\")});\n\n    if (parser) {\n        for (auto\u0026\u0026 [key, value] : parser.cached_result()) {\n            spdlog::info(U8(\"{} = {}\"), key, value.raw_value);\n        }\n\n        if (auto m = parser.to_model\u003cmodel\u003e()) {\n            spdlog::info(json(m).dump(4));\n        }\n        \n        auto joint = join_with(parser.unmatched_args(), std::string_view{U8(\",\")});\n\n        spdlog::info(U8(\"Unmatched args: {}\"), std::string{joint.begin(), joint.end()});\n    }\n}\n```\n\n\n\n## Acknowledgements\n\nThis library includes several third-party submodules, each of which is exceptional and has garnered many stars on\nGitHub.\n\n![](https://avatars.githubusercontent.com/u/159488?s=48\u0026v=4)[nlohmann/json: JSON for Modern C++](https://github.com/nlohmann/json)\n\n![](https://avatars.githubusercontent.com/u/7280830?s=48\u0026v=4)[fmtlib/fmt: A modern formatting library](https://github.com/fmtlib/fmt)\n\n![](https://avatars.githubusercontent.com/u/6154722?s=48\u0026v=4)[microsoft/cpprestsdk: The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design.](https://github.com/microsoft/cpprestsdk)\n\n![](https://avatars.githubusercontent.com/u/3279138?s=48\u0026v=4)[openssl/openssl: TLS/SSL and crypto library](https://github.com/openssl/openssl)\n\n![](https://avatars.githubusercontent.com/u/6052198?s=48\u0026v=4)[gabime/spdlog: Fast C++ logging library.](https://github.com/gabime/spdlog)\n\n![](https://avatars.githubusercontent.com/u/3170529?s=48\u0026v=4)[boostorg/boost: Super-project for modularized Boost](https://github.com/boostorg/boost)\n\n\u003cimg src=\"https://avatars.githubusercontent.com/u/45075615?s=48\u0026v=4\" width=\"56\" height=\"56\"\u003e[zlib-ng/zlib-ng: zlib replacement with optimizations for \"next generation\" systems.](https://github.com/zlib-ng/zlib-ng)\n\n![](https://avatars.githubusercontent.com/u/69631?s=48\u0026v=4)[facebook/zstd: Zstandard - Fast real-time compression algorithm](https://github.com/facebook/zstd)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frefvalue%2Fcpp-essence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frefvalue%2Fcpp-essence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frefvalue%2Fcpp-essence/lists"}