diff --git a/.gitignore b/.gitignore index 193b498cf7..e7356c35f5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ out/ **/bin/ **/build*/ -**/lib*/ +**/lib/ **/_build*/ # CMake specific settings @@ -12,7 +12,6 @@ CMakeUserPresets.json **/Testing/ # IDE files -.claude/ .idea/ .vs/ .vscode/ @@ -20,10 +19,10 @@ CMakeUserPresets.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json -.claude/ *.swp *~ _ReSharper* +__pycache__/ *.log .cache/ compile_commands.json @@ -63,6 +62,9 @@ pr_description.md /size_tests /tmp_benchmark /exterior + pr.md + +/vc140.pdb /tmp/ tmp/ diff --git a/CMakeLists.txt b/CMakeLists.txt index f8706fe5de..74c7a528ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ -cmake_minimum_required(VERSION 3.21) +cmake_minimum_required(VERSION 4.4) + +set(CACHE{CMAKE_EXPERIMENTAL_CXX_IMPORT_STD} VALUE "f35a9ac6-8463-4d38-8eec-5d6008153e7d") include(cmake/prelude.cmake) @@ -8,6 +10,12 @@ project( LANGUAGES CXX ) +option(GLAZE_ENABLE_MODULES "Enable modules with import std" ON) # or GLAZE_GENERATE_HEADERS ?? + +if (GLAZE_ENABLE_MODULES) + set(CMAKE_CXX_MODULE_STD 1) +endif() + include(cmake/project-is-top-level.cmake) include(cmake/variables.cmake) @@ -15,25 +23,33 @@ if (PROJECT_IS_TOP_LEVEL) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) endif() -add_library(glaze_glaze INTERFACE) +if(GLAZE_ENABLE_MODULES) + add_library(glaze_glaze STATIC) + if (PROJECT_IS_TOP_LEVEL) + set_target_properties(glaze_glaze PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + set(GLAZE_LIB_TYPE PUBLIC) +else() + add_library(glaze_glaze INTERFACE) + set(GLAZE_LIB_TYPE INTERFACE) +endif() add_library(glaze::glaze ALIAS glaze_glaze) - if (MSVC) string(REGEX MATCH "\/cl(.exe)?$" matched_cl ${CMAKE_CXX_COMPILER}) if (matched_cl) # for a C++ standards compliant preprocessor, not needed for clang-cl target_compile_options(glaze_glaze INTERFACE "/Zc:preprocessor" /permissive- /Zc:lambda) - + if(PROJECT_IS_TOP_LEVEL) - target_compile_options(glaze_glaze INTERFACE + target_compile_options(glaze_glaze INTERFACE $<$:/GL> $<$:/GL>) - target_link_options(glaze_glaze INTERFACE + target_link_options(glaze_glaze INTERFACE $<$:/LTCG /INCREMENTAL:NO> $<$:/LTCG /INCREMENTAL:NO>) endif() - endif() + endif() else() # Only apply -Wno-missing-braces for C and C++ compilation to avoid breaking ISPC and other language builds target_compile_options(${PROJECT_NAME}_${PROJECT_NAME} INTERFACE @@ -42,12 +58,15 @@ endif() set_property(TARGET ${PROJECT_NAME}_${PROJECT_NAME} PROPERTY EXPORT_NAME glaze) -target_compile_features(${PROJECT_NAME}_${PROJECT_NAME} INTERFACE cxx_std_23) +target_compile_features(glaze_glaze ${GLAZE_LIB_TYPE} cxx_std_23) target_include_directories( - ${PROJECT_NAME}_${PROJECT_NAME} ${warning_guard} - INTERFACE "$" + glaze_glaze ${warning_guard} + PUBLIC + "$" ) +include(cmake/modules-files.cmake) + option(glaze_INSTALL "Generate installation rules for glaze" "${PROJECT_IS_TOP_LEVEL}") if(glaze_INSTALL AND NOT CMAKE_SKIP_INSTALL_RULES) include(cmake/install-rules.cmake) @@ -75,7 +94,7 @@ if(glaze_BUILD_EXAMPLES) add_subdirectory(examples) endif() -option(glaze_EETF_FORMAT "Enable Erlang external term format parsing" OFF) +option(glaze_EETF_FORMAT "Enable Erlang external term format parsing" OFF) # TODO: Convert if(glaze_EETF_FORMAT) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/CMakePresets.json b/CMakePresets.json index 40415b6d58..96c1b2ad24 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,120 +1,149 @@ { - "version": 3, - "cmakeMinimumRequired": { - "major": 3, - "minor": 23, - "patch": 0 + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 0 + }, + "configurePresets": [ + { + "name": "clang-debug", + "displayName": "Clang Debug", + "description": "Debug build using Clang compiler", + "binaryDir": "${sourceDir}/build/debug", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "/usr/bin/clang", + "CMAKE_CXX_COMPILER": "/usr/bin/clang++", + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "glaze_DEVELOPER_MODE": true, + "BUILD_TESTING": true, + "glaze_BUILD_INTEROP": true, + "CMAKE_CXX_FLAGS": "-stdlib=libc++", + "CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++", + "CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++", + "CMAKE_MODULE_LINKER_FLAGS": "-stdlib=libc++" + } }, - "configurePresets": [ - { - "name": "clang-debug", - "displayName": "Clang Debug", - "description": "Debug build using Clang compiler", - "binaryDir": "${sourceDir}/build/debug", - "generator": "Ninja", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_C_COMPILER": "/usr/bin/clang", - "CMAKE_CXX_COMPILER": "/usr/bin/clang++", - "CMAKE_EXPORT_COMPILE_COMMANDS": true, - "glaze_DEVELOPER_MODE": true, - "BUILD_TESTING": true, - "glaze_BUILD_INTEROP": true, - "CMAKE_CXX_FLAGS": "-stdlib=libc++", - "CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++", - "CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++", - "CMAKE_MODULE_LINKER_FLAGS": "-stdlib=libc++" - } - }, - { - "name": "clang-release", - "displayName": "Clang Release", - "description": "Release build using Clang compiler", - "binaryDir": "${sourceDir}/build/release", - "generator": "Ninja", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_C_COMPILER": "/usr/bin/clang", - "CMAKE_CXX_COMPILER": "/usr/bin/clang++", - "CMAKE_EXPORT_COMPILE_COMMANDS": true, - "glaze_DEVELOPER_MODE": true, - "BUILD_TESTING": true, - "glaze_BUILD_INTEROP": true, - "CMAKE_CXX_FLAGS": "-stdlib=libc++", - "CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++", - "CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++", - "CMAKE_MODULE_LINKER_FLAGS": "-stdlib=libc++" - } - }, - { - "name": "gcc-debug", - "displayName": "GCC Debug", - "description": "Debug build using GCC compiler", - "binaryDir": "${sourceDir}/build/debug-gcc", - "generator": "Ninja", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_C_COMPILER": "/usr/bin/gcc", - "CMAKE_CXX_COMPILER": "/usr/bin/g++", - "CMAKE_EXPORT_COMPILE_COMMANDS": true, - "glaze_DEVELOPER_MODE": true, - "BUILD_TESTING": true, - "glaze_BUILD_INTEROP": true - } - }, - { - "name": "gcc-release", - "displayName": "GCC Release", - "description": "Release build using GCC compiler", - "binaryDir": "${sourceDir}/build/release-gcc", - "generator": "Ninja", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_C_COMPILER": "/usr/bin/gcc", - "CMAKE_CXX_COMPILER": "/usr/bin/g++", - "CMAKE_EXPORT_COMPILE_COMMANDS": true, - "glaze_DEVELOPER_MODE": true, - "BUILD_TESTING": true, - "glaze_BUILD_INTEROP": true - } - } - ], - "buildPresets": [ - { - "name": "clang-debug", - "configurePreset": "clang-debug" - }, - { - "name": "clang-release", - "configurePreset": "clang-release" - }, - { - "name": "gcc-debug", - "configurePreset": "gcc-debug" - }, - { - "name": "gcc-release", - "configurePreset": "gcc-release" - } - ], - "testPresets": [ - { - "name": "clang-debug", - "displayName": "Test Clang Debug", - "configurePreset": "clang-debug", - "output": { - "verbosity": "verbose", - "outputOnFailure": true - } - }, - { - "name": "gcc-debug", - "displayName": "Test GCC Debug", - "configurePreset": "gcc-debug", - "output": { - "verbosity": "verbose", - "outputOnFailure": true - } - } - ] + { + "name": "clang-release", + "displayName": "Clang Release", + "description": "Release build using Clang compiler", + "binaryDir": "${sourceDir}/build/release", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_C_COMPILER": "/usr/bin/clang", + "CMAKE_CXX_COMPILER": "/usr/bin/clang++", + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "glaze_DEVELOPER_MODE": true, + "BUILD_TESTING": true, + "glaze_BUILD_INTEROP": true, + "CMAKE_CXX_FLAGS": "-stdlib=libc++", + "CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++", + "CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++", + "CMAKE_MODULE_LINKER_FLAGS": "-stdlib=libc++" + } + }, + { + "name": "gcc-debug", + "displayName": "GCC Debug", + "description": "Debug build using GCC compiler", + "binaryDir": "${sourceDir}/build/debug-gcc", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "/usr/bin/gcc", + "CMAKE_CXX_COMPILER": "/usr/bin/g++", + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "glaze_DEVELOPER_MODE": true, + "BUILD_TESTING": true, + "glaze_BUILD_INTEROP": true + } + }, + { + "name": "gcc-release", + "displayName": "GCC Release", + "description": "Release build using GCC compiler", + "binaryDir": "${sourceDir}/build/release-gcc", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_C_COMPILER": "/usr/bin/gcc", + "CMAKE_CXX_COMPILER": "/usr/bin/g++", + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "glaze_DEVELOPER_MODE": true, + "BUILD_TESTING": true, + "glaze_BUILD_INTEROP": true + } + }, + { + "name": "windows-base", + "description": "Base preset for MSVC v14.52", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "toolset": { + "value": "v145,host=x64,version=14.52" + } + }, + { + "name": "x64", + "displayName": "x64 Debug (MSVC v14.52 Preview)", + "inherits": "windows-base", + "architecture": { + "value": "x64", + "strategy": "external" + } + } + ], + "buildPresets": [ + { + "name": "clang-debug", + "configurePreset": "clang-debug" + }, + { + "name": "clang-release", + "configurePreset": "clang-release" + }, + { + "name": "gcc-debug", + "configurePreset": "gcc-debug" + }, + { + "name": "gcc-release", + "configurePreset": "gcc-release" + }, + { + "name": "x64-build", + "configurePreset": "x64" + } + ], + "testPresets": [ + { + "name": "clang-debug", + "displayName": "Test Clang Debug", + "configurePreset": "clang-debug", + "output": { + "verbosity": "verbose", + "outputOnFailure": true + } + }, + { + "name": "gcc-debug", + "displayName": "Test GCC Debug", + "configurePreset": "gcc-debug", + "output": { + "verbosity": "verbose", + "outputOnFailure": true + } + } + ] } diff --git a/README.md b/README.md index b4dd193bbb..e3727d2fe8 100644 --- a/README.md +++ b/README.md @@ -20,52 +20,14 @@ Formats Supported: > > Glaze is getting HTTP support with REST servers, clients, websockets, and more. The networking side of Glaze is under active development, and while it is usable and feedback is desired, the API is likely to be changing and improving. +> [!TIP] +> Glaze now supports [P2996 "Reflection for C++26"](https://wg21.link/P2996). When enabled, P2996 unlocks capabilities that aren't possible with traditional compile-time reflection. For more details, see [Reflection for C++26 section](#c++26-p2996-reflection-support). + ## With C++23 compile time reflection for MSVC, Clang, and GCC! - Read/write aggregate initializable structs without writing any metadata or macros! - See [example on Compiler Explorer](https://gcc.godbolt.org/z/T4To5fKfz) -## C++26 P2996 Reflection Support - -Glaze now supports [P2996 "Reflection for C++26"](https://wg21.link/P2996). When enabled, P2996 unlocks capabilities that aren't possible with traditional compile-time reflection. - -
P2996 reflection capabilities and examples: - -- **Non-aggregate types** — classes with constructors, virtual functions, and inheritance just work -- **Automatic enum serialization** — no `glz::meta` needed, enums serialize to strings automatically -- **Unlimited struct members** — no 128-member cap -- **Private member access** — reflect on all members regardless of access specifiers -- **Standardized** — no compiler-specific hacks, built on `std::meta` - -```cpp -// Classes with constructors — just works with P2996 -class User { -public: - std::string name; - int age; - User() = default; - User(std::string n, int a) : name(std::move(n)), age(a) {} -}; - -User u{"Alice", 30}; -auto json = glz::write_json(u).value_or("error"); -// {"name":"Alice","age":30} - -// Enums serialize as strings — no glz::meta required -enum class Color { Red, Green, Blue }; -Color c = Color::Green; - -struct reflect_enums_opts : glz::opts { - bool reflect_enums = true; -}; -auto color_json = glz::write(c).value_or("error"); -// "Green" -``` - -Supported compilers: [GCC 16+](https://gcc.gnu.org/gcc-16/changes.html) (`-std=c++26 -freflection`) and [Bloomberg clang-p2996](https://github.com/bloomberg/clang-p2996). See the [P2996 documentation](https://stephenberry.github.io/glaze/p2996-reflection/) for setup and details. - -
- ## [📖 Documentation](https://stephenberry.github.io/glaze/) See this README, the [Glaze Documentation Page](https://stephenberry.github.io/glaze/), or [docs folder](https://github.com/stephenberry/glaze/tree/main/docs) for documentation. @@ -86,6 +48,7 @@ See this README, the [Glaze Documentation Page](https://stephenberry.github.io/g - No exceptions (compiles with `-fno-exceptions`) - If you desire helpers that throw for cleaner syntax see [Glaze Exceptions](https://stephenberry.github.io/glaze/exceptions/) - No runtime type information necessary (compiles with `-fno-rtti`) +- Modules native - [JSON Schema generation](https://stephenberry.github.io/glaze/json-schema/) - [Partial Read](https://stephenberry.github.io/glaze/partial-read/) and [Partial Write](https://stephenberry.github.io/glaze/partial-write/) support - [Streaming I/O](https://stephenberry.github.io/glaze/streaming/) for reading/writing large files with bounded memory @@ -133,135 +96,74 @@ BEVE size: 611 bytes *BEVE packs more efficiently than JSON, so transporting the same data is even faster. -## Examples +## Compiler/System Support -> [!TIP] -> -> See the [example_json](https://github.com/stephenberry/glaze/blob/main/tests/example_json/example_json.cpp) unit test for basic examples of how to use Glaze. See [json_test](https://github.com/stephenberry/glaze/blob/main/tests/json_test/json_test.cpp) for an extensive test of features. +- Requires C++23 +- Tested for both 64bit and 32bit +- Supports both little-endian and big-endian systems -Your struct will automatically get reflected! No metadata is required by the user. +[Actions](https://github.com/stephenberry/glaze/actions) build and test with [Clang](https://clang.llvm.org) (18+), [MSVC](https://visualstudio.microsoft.com/vs/features/cplusplus/) (Visual Studio 2026 MSVC Build Tools 14.50), and [GCC](https://gcc.gnu.org) (13+) on Apple, Windows, and Linux. Big-endian is tested via QEMU emulation on s390x. -```c++ -struct my_struct -{ - int i = 287; - double d = 3.14; - std::string hello = "Hello World"; - std::array arr = { 1, 2, 3 }; - std::map map{{"one", 1}, {"two", 2}}; -}; -``` - -**JSON** (prettified) +![clang build](https://github.com/stephenberry/glaze/actions/workflows/clang.yml/badge.svg) ![gcc build](https://github.com/stephenberry/glaze/actions/workflows/gcc.yml/badge.svg) ![msvc build](https://github.com/stephenberry/glaze/actions/workflows/msvc.yml/badge.svg) -```json -{ - "i": 287, - "d": 3.14, - "hello": "Hello World", - "arr": [ - 1, - 2, - 3 - ], - "map": { - "one": 1, - "two": 2 - } -} -``` +> Glaze seeks to maintain compatibility with the latest three versions of GCC and Clang, as well as the latest version of MSVC and Apple Clang (Xcode). And, we aim to only drop old versions with major releases. -**Write JSON** +## How To Use Glaze -```c++ -my_struct s{}; -std::string buffer = glz::write_json(s).value_or("error"); -``` +For more details and a walkthrough on the installation, see [docs/installation.md](https://github.com/stephenberry/glaze/blob/main/docs/installation.md). -or +### [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) +```cmake +include(FetchContent) -```c++ -my_struct s{}; -std::string buffer{}; -auto ec = glz::write_json(s, buffer); -if (ec) { - // handle error -} -``` +FetchContent_Declare( + glaze + GIT_REPOSITORY https://github.com/stephenberry/glaze.git + GIT_TAG main + GIT_SHALLOW TRUE +) -**Read JSON** +FetchContent_MakeAvailable(glaze) -```c++ -std::string buffer = R"({"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}})"; -auto s = glz::read_json(buffer); -if (s) // check std::expected -{ - s.value(); // s.value() is a my_struct populated from buffer -} +target_link_libraries(${PROJECT_NAME} PRIVATE glaze::glaze) ``` -or +### [vcpkg](https://vcpkg.io/en/package/glaze) -```c++ -std::string buffer = R"({"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}})"; -my_struct s{}; -auto ec = glz::read_json(s, buffer); // populates s from buffer -if (ec) { - // handle error -} ``` - -### Read/Write From File - -```c++ -auto ec = glz::read_file_json(obj, "./obj.json", std::string{}); -auto ec = glz::write_file_json(obj, "./obj.json", std::string{}); +vcpkg add port glaze ``` -> [!IMPORTANT] -> -> The file name (2nd argument), must be null terminated. - -### Writing to Streams - -For streaming to `std::ostream` destinations (files, network, etc.) with bounded memory: - -```c++ -#include "glaze/core/ostream_buffer.hpp" +```cmake +find_package(glaze CONFIG REQUIRED) -std::ofstream file("output.json"); -glz::basic_ostream_buffer buffer(file); // Concrete type for performance -auto ec = glz::write_json(obj, buffer); +target_link_libraries(TPP PRIVATE glaze::glaze) ``` -The buffer flushes incrementally during serialization, enabling arbitrarily large outputs with fixed memory. See [Streaming I/O](https://stephenberry.github.io/glaze/streaming/) for details on buffer types and stream concepts. - -### Reading from Streams +### [Conan](https://conan.io) -For streaming from `std::istream` sources (files, network, etc.) with bounded memory: +- Included in [Conan Center](https://conan.io/center/) ![Conan Center](https://img.shields.io/conan/v/glaze) -```c++ -#include "glaze/core/istream_buffer.hpp" +``` +find_package(glaze REQUIRED) -std::ifstream file("input.json"); -glz::basic_istream_buffer buffer(file); -my_struct obj; -auto ec = glz::read_json(obj, buffer); +target_link_libraries(main PRIVATE glaze::glaze) ``` -The buffer refills automatically during parsing, enabling reading of arbitrarily large inputs with fixed memory. See [Streaming I/O](https://stephenberry.github.io/glaze/streaming/) for NDJSON processing and other streaming patterns. +### [build2](https://build2.org) -## Compiler/System Support +- Available on [cppget](https://cppget.org/libglaze) -- Requires C++23 -- Tested for both 64bit and 32bit -- Supports both little-endian and big-endian systems +``` +import libs = libglaze%lib{glaze} +``` -[Actions](https://github.com/stephenberry/glaze/actions) build and test with [Clang](https://clang.llvm.org) (18+), [MSVC](https://visualstudio.microsoft.com/vs/features/cplusplus/) (Visual Studio 2026 MSVC Build Tools 14.50), and [GCC](https://gcc.gnu.org) (13+) on apple, windows, and linux. Big-endian is tested via QEMU emulation on s390x. +### Arch Linux -![clang build](https://github.com/stephenberry/glaze/actions/workflows/clang.yml/badge.svg) ![gcc build](https://github.com/stephenberry/glaze/actions/workflows/gcc.yml/badge.svg) ![msvc build](https://github.com/stephenberry/glaze/actions/workflows/msvc.yml/badge.svg) +- [Official Arch repository](https://archlinux.org/packages/extra/any/glaze/) +- AUR git package: [glaze-git](https://aur.archlinux.org/packages/glaze-git) -> Glaze seeks to maintain compatibility with the latest three versions of GCC and Clang, as well as the latest version of MSVC and Apple Clang (Xcode). And, we aim to only drop old versions with major releases. +### See this [Example Repository](https://github.com/stephenberry/glaze_example) for how to use Glaze in a new project ### MSVC Compiler Flags @@ -335,52 +237,166 @@ auto ec = glz::read(obj, buffer); See [Optimization Levels](https://stephenberry.github.io/glaze/optimization-levels/) for full details. -## How To Use Glaze +## See [FAQ](https://stephenberry.github.io/glaze/FAQ/) for Frequently Asked Questions +--- -### [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) -```cmake -include(FetchContent) +## C++26 P2996 Reflection Support -FetchContent_Declare( - glaze - GIT_REPOSITORY https://github.com/stephenberry/glaze.git - GIT_TAG main - GIT_SHALLOW TRUE -) +
P2996 reflection capabilities and examples: -FetchContent_MakeAvailable(glaze) +- **Non-aggregate types** — classes with constructors, virtual functions, and inheritance just work +- **Automatic enum serialization** — no `glz::meta` needed, enums serialize to strings automatically +- **Unlimited struct members** — no 128-member cap +- **Private member access** — reflect on all members regardless of access specifiers +- **Standardized** — no compiler-specific hacks, built on `std::meta` -target_link_libraries(${PROJECT_NAME} PRIVATE glaze::glaze) +```cpp +// Classes with constructors — just works with P2996 +class User { +public: + std::string name; + int age; + User() = default; + User(std::string n, int a) : name(std::move(n)), age(a) {} +}; + +User u{"Alice", 30}; +auto json = glz::write_json(u).value_or("error"); +// {"name":"Alice","age":30} + +// Enums serialize as strings — no glz::meta required +enum class Color { Red, Green, Blue }; +Color c = Color::Green; + +struct reflect_enums_opts : glz::opts { + bool reflect_enums = true; +}; +auto color_json = glz::write(c).value_or("error"); +// "Green" ``` -### [Conan](https://conan.io) +Supported compilers: [GCC 16+](https://gcc.gnu.org/gcc-16/changes.html) (`-std=c++26 -freflection`) and [Bloomberg clang-p2996](https://github.com/bloomberg/clang-p2996). See the [P2996 documentation](https://stephenberry.github.io/glaze/p2996-reflection/) for setup and details. -- Included in [Conan Center](https://conan.io/center/) ![Conan Center](https://img.shields.io/conan/v/glaze) +
+ +## Examples + +> [!TIP] +> +> See the [example_json](https://github.com/stephenberry/glaze/blob/main/tests/example_json/example_json.cpp) unit test for basic examples of how to use Glaze. See [json_test](https://github.com/stephenberry/glaze/blob/main/tests/json_test/json_test.cpp) for an extensive test of features. + +Your struct will automatically get reflected! No metadata is required by the user. + +```c++ +struct my_struct +{ + int i = 287; + double d = 3.14; + std::string hello = "Hello World"; + std::array arr = { 1, 2, 3 }; + std::map map{{"one", 1}, {"two", 2}}; +}; ``` -find_package(glaze REQUIRED) -target_link_libraries(main PRIVATE glaze::glaze) +**JSON** (prettified) + +```json +{ + "i": 287, + "d": 3.14, + "hello": "Hello World", + "arr": [ + 1, + 2, + 3 + ], + "map": { + "one": 1, + "two": 2 + } +} ``` -### [build2](https://build2.org) +**Write JSON** -- Available on [cppget](https://cppget.org/libglaze) +```c++ +my_struct s{}; +std::string buffer = glz::write_json(s).value_or("error"); +``` + +or +```c++ +my_struct s{}; +std::string buffer{}; +auto ec = glz::write_json(s, buffer); +if (ec) { + // handle error +} ``` -import libs = libglaze%lib{glaze} + +**Read JSON** + +```c++ +std::string buffer = R"({"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}})"; +auto s = glz::read_json(buffer); +if (s) // check std::expected +{ + s.value(); // s.value() is a my_struct populated from buffer +} ``` -### Arch Linux +or -- [Official Arch repository](https://archlinux.org/packages/extra/any/glaze/) -- AUR git package: [glaze-git](https://aur.archlinux.org/packages/glaze-git) +```c++ +std::string buffer = R"({"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}})"; +my_struct s{}; +auto ec = glz::read_json(s, buffer); // populates s from buffer +if (ec) { + // handle error +} +``` -### See this [Example Repository](https://github.com/stephenberry/glaze_example) for how to use Glaze in a new project +### Read/Write From File ---- +```c++ +auto ec = glz::read_file_json(obj, "./obj.json", std::string{}); +auto ec = glz::write_file_json(obj, "./obj.json", std::string{}); +``` -## See [FAQ](https://stephenberry.github.io/glaze/FAQ/) for Frequently Asked Questions +> [!IMPORTANT] +> +> The file name (2nd argument), must be null terminated. + +### Writing to Streams + +For streaming to `std::ostream` destinations (files, network, etc.) with bounded memory: + +```c++ +#include "glaze/core/ostream_buffer.hpp" + +std::ofstream file("output.json"); +glz::basic_ostream_buffer buffer(file); // Concrete type for performance +auto ec = glz::write_json(obj, buffer); +``` + +The buffer flushes incrementally during serialization, enabling arbitrarily large outputs with fixed memory. See [Streaming I/O](https://stephenberry.github.io/glaze/streaming/) for details on buffer types and stream concepts. + +### Reading from Streams + +For streaming from `std::istream` sources (files, network, etc.) with bounded memory: + +```c++ +#include "glaze/core/istream_buffer.hpp" + +std::ifstream file("input.json"); +glz::basic_istream_buffer buffer(file); +my_struct obj; +auto ec = glz::read_json(obj, buffer); +``` + +The buffer refills automatically during parsing, enabling reading of arbitrarily large inputs with fixed memory. See [Streaming I/O](https://stephenberry.github.io/glaze/streaming/) for NDJSON processing and other streaming patterns. # Explicit Metadata @@ -412,7 +428,7 @@ struct my_struct int i = 287; double d = 3.14; std::string hello = "Hello World"; - std::array arr = { 1, 2, 3 }; + std::array arr = { 1, 2, 3 }; std::map map{{"one", 1}, {"two", 2}}; struct glaze { @@ -467,7 +483,7 @@ struct server_status { std::string name; std::string region; - uint64_t active_sessions{}; + std::uint64_t active_sessions{}; std::optional maintenance; double cpu_percent{}; }; @@ -526,7 +542,7 @@ static_assert(glz::reflect::keys[0] == "i"); // Access keys ```c++ struct test_type { - int32_t int1{}; + std::int32_t int1{}; int64_t int2{}; }; @@ -551,15 +567,15 @@ For common use cases or cases where a specific member variable should have speci ```c++ struct custom_encoding { - uint64_t x{}; + std::uint64_t x{}; std::string y{}; - std::array z{}; + std::array z{}; void read_x(const std::string& s) { x = std::stoi(s); } - uint64_t write_x() { + std::uint64_t write_x() { return x; } @@ -589,7 +605,7 @@ suite custom_encoding_test = [] { expect(!glz::read_json(obj, s)); expect(obj.x == 3); expect(obj.y == "helloworld"); - expect(obj.z == std::array{1, 2, 3}); + expect(obj.z == std::array{1, 2, 3}); }; "custom_writing"_test = [] { @@ -853,7 +869,7 @@ my_struct obj{}; auto ec = glz::read_json(obj, buffer); if (!ec) { // Success: ec.count contains bytes consumed - size_t bytes_consumed = ec.count; + std::size_t bytes_consumed = ec.count; // bytes_consumed == 13 (entire JSON object) } ``` @@ -1292,7 +1308,7 @@ You can parse quoted JSON numbers directly to types like `double`, `int`, etc. b ```c++ struct A { double x; - std::vector y; + std::vector y; }; template <> @@ -1308,7 +1324,7 @@ struct glz::meta { } ``` -The quoted JSON numbers will be parsed directly into the `double` and `std::vector`. The `glz::quoted` function works for nested objects and arrays as well. +The quoted JSON numbers will be parsed directly into the `double` and `std::vector`. The `glz::quoted` function works for nested objects and arrays as well. ## JSON Lines (NDJSON) Support diff --git a/benchmarks/lazy_benchmark.cpp b/benchmarks/lazy_benchmark.cpp index 0b9f1fa7ef..a0f4d66370 100644 --- a/benchmarks/lazy_benchmark.cpp +++ b/benchmarks/lazy_benchmark.cpp @@ -7,6 +7,9 @@ #include "glaze/json.hpp" // Struct for deserialization benchmarks + +using std::size_t; + struct BenchUser { int64_t id{}; diff --git a/benchmarks/simple_float_benchmark.cpp b/benchmarks/simple_float_benchmark.cpp index 8979b8cd64..2d338ec6bc 100644 --- a/benchmarks/simple_float_benchmark.cpp +++ b/benchmarks/simple_float_benchmark.cpp @@ -10,6 +10,11 @@ #include "glaze/util/zmij.hpp" // Generate test data + +using std::uint32_t; +using std::uint64_t; +using std::size_t; + std::vector generate_random_floats(size_t count, uint32_t seed = 12345) { std::mt19937 rng(seed); diff --git a/benchmarks/skip_ws_benchmark.cpp b/benchmarks/skip_ws_benchmark.cpp index c83c066ef8..a61489032f 100644 --- a/benchmarks/skip_ws_benchmark.cpp +++ b/benchmarks/skip_ws_benchmark.cpp @@ -26,6 +26,11 @@ // ============================================================================ // Scalar skip_ws (lookup table, 1 byte at a time) // ============================================================================ + +using std::uint32_t; +using std::uint64_t; +using std::size_t; + namespace scalar { inline constexpr std::array whitespace_table = [] { diff --git a/benchmarks/string_write_benchmark.cpp b/benchmarks/string_write_benchmark.cpp index 92cf0b9fcc..5b968d83b7 100644 --- a/benchmarks/string_write_benchmark.cpp +++ b/benchmarks/string_write_benchmark.cpp @@ -19,6 +19,10 @@ // ============================================================================ // Pure ASCII lowercase, no escaping needed + +using std::uint64_t; +using std::size_t; + static std::string gen_ascii(size_t len, uint64_t seed = 42) { std::mt19937 rng(seed); diff --git a/cmake/dev-mode.cmake b/cmake/dev-mode.cmake index 828bca8d14..21e5166ae7 100644 --- a/cmake/dev-mode.cmake +++ b/cmake/dev-mode.cmake @@ -13,7 +13,7 @@ if(BUILD_TESTING) endif() if (glaze_ENABLE_FUZZING) - add_subdirectory(fuzzing) + #add_subdirectory(fuzzing) # temporary endif() # Done in developer mode only, so users won't be bothered by this :) diff --git a/cmake/install-rules.cmake b/cmake/install-rules.cmake index cae895a72f..2f24d6b47e 100644 --- a/cmake/install-rules.cmake +++ b/cmake/install-rules.cmake @@ -1,21 +1,19 @@ # Project is configured with no languages, so tell GNUInstallDirs the lib dir set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "") +set(CMAKE_INSTALL_INCLUDEDIR "modules" CACHE PATH "") + include(CMakePackageConfigHelpers) include(GNUInstallDirs) # find_package() call for consumers to find this project set(package glaze) -install( - DIRECTORY include/ - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT glaze_Development -) - install( TARGETS glaze_glaze EXPORT glazeTargets + COMPONENT glaze_Development + FILE_SET CXX_MODULES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) @@ -78,6 +76,7 @@ install( EXPORT glazeTargets NAMESPACE glaze:: DESTINATION "${glaze_INSTALL_CMAKEDIR}" + CXX_MODULES_DIRECTORY cxx-modules COMPONENT glaze_Development ) diff --git a/cmake/modules-files.cmake b/cmake/modules-files.cmake new file mode 100644 index 0000000000..eb3ddca760 --- /dev/null +++ b/cmake/modules-files.cmake @@ -0,0 +1,421 @@ +## TODO: sort + + +# Top-level +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/glaze.ixx + modules/glaze/json.ixx + modules/glaze/jsonb.ixx + modules/glaze/cbor.ixx + modules/glaze/bson.ixx + modules/glaze/beve.ixx + modules/glaze/csv.ixx + modules/glaze/chrono.ixx + modules/glaze/version.ixx + modules/glaze/glaze_exceptions.ixx + modules/glaze/msgpack.ixx + modules/glaze/toml.ixx +) + +# core +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/core/array_apply.ixx + modules/glaze/core/as_array_wrapper.ixx + modules/glaze/core/buffer_traits.ixx + modules/glaze/core/cast.ixx + modules/glaze/core/chrono.ixx + modules/glaze/core/common.ixx + modules/glaze/core/constraint.ixx + modules/glaze/core/context.ixx + modules/glaze/core/convert_struct.ixx + modules/glaze/core/custom.ixx + modules/glaze/core/custom_meta.ixx + modules/glaze/core/format_str.ixx + modules/glaze/core/istream_buffer.ixx + modules/glaze/core/manage.ixx + modules/glaze/core/meta.ixx + modules/glaze/core/meta_fwd.ixx + modules/glaze/core/optimization_level.ixx + modules/glaze/core/opts.ixx + modules/glaze/core/ostream_buffer.ixx + modules/glaze/core/ptr.ixx + modules/glaze/core/read.ixx + modules/glaze/core/reflect.ixx + modules/glaze/core/seek.ixx + modules/glaze/core/std_error_code.ixx + modules/glaze/core/streaming_state.ixx + modules/glaze/core/to.ixx + modules/glaze/core/traits.ixx + modules/glaze/core/wrapper_traits.ixx + modules/glaze/core/write.ixx + modules/glaze/core/write_chars.ixx + modules/glaze/core/write_wrappers.ixx +) + +# json +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/json/chrono_format.ixx + modules/glaze/json/escape_unicode.ixx + modules/glaze/json/float_format.ixx + modules/glaze/json/generic_fwd.ixx + modules/glaze/json/generic.ixx + modules/glaze/json/invoke.ixx + modules/glaze/json/jmespath.ixx + modules/glaze/json/json_concepts.ixx + modules/glaze/json/json_format.ixx + modules/glaze/json/json_ptr.ixx + modules/glaze/json/json_stream.ixx + modules/glaze/json/lazy.ixx + modules/glaze/json/max_write_precision.ixx + modules/glaze/json/minify.ixx + modules/glaze/json/ndjson.ixx + modules/glaze/json/patch.ixx + modules/glaze/json/prettify.ixx + modules/glaze/json/ptr.ixx + modules/glaze/json/raw_string.ixx + modules/glaze/json/read.ixx + modules/glaze/json/schema.ixx + modules/glaze/json/skip.ixx + modules/glaze/json/study.ixx + modules/glaze/json/wrappers.ixx + modules/glaze/json/write.ixx + modules/glaze/json/flatten_map.ixx +) + +# utils +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/util/string_literal.ixx + modules/glaze/util/expected.ixx + modules/glaze/util/dump.ixx + modules/glaze/util/convert.ixx + modules/glaze/util/parse.ixx + modules/glaze/util/nullable_traits.ixx + modules/glaze/util/atoi.ixx + modules/glaze/util/for_each.ixx + modules/glaze/util/type_traits.ixx + modules/glaze/util/bit.ixx + modules/glaze/util/compare.ixx + modules/glaze/util/glaze_fast_float.ixx + modules/glaze/util/simple_float.ixx + modules/glaze/util/fast_float.ixx + modules/glaze/util/variant.ixx + modules/glaze/util/itoa.ixx + modules/glaze/util/bit_array.ixx + modules/glaze/util/help.ixx + modules/glaze/util/tuple.ixx + modules/glaze/util/validate.ixx + modules/glaze/util/primes_64.ixx + modules/glaze/util/dtoa.ixx + modules/glaze/util/itoa_40kb.ixx + modules/glaze/util/dragonbox.ixx + modules/glaze/util/buffer_pool.ixx + modules/glaze/util/progress_bar.ixx + modules/glaze/util/key_transformers.ixx + modules/glaze/util/uuid.ixx + modules/glaze/util/zmij.ixx +) + +# concepts +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/concepts/container_concepts.ixx +) + +# api +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/api/hash.ixx + modules/glaze/api/tuplet.ixx + modules/glaze/api/type_support.ixx + modules/glaze/api/xxh64.ixx + modules/glaze/api/impl.ixx + modules/glaze/api/api.ixx + modules/glaze/api/trait.ixx + modules/glaze/api/lib.ixx +) + +# api/std +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/api/std/array.ixx + modules/glaze/api/std/deque.ixx + modules/glaze/api/std/functional.ixx + modules/glaze/api/std/list.ixx + modules/glaze/api/std/map.ixx + modules/glaze/api/std/optional.ixx + modules/glaze/api/std/set.ixx + modules/glaze/api/std/shared_ptr.ixx + modules/glaze/api/std/span.ixx + modules/glaze/api/std/string.ixx + modules/glaze/api/std/tuple.ixx + modules/glaze/api/std/unique_ptr.ixx + modules/glaze/api/std/unordered_map.ixx + modules/glaze/api/std/unordered_set.ixx + modules/glaze/api/std/variant.ixx + modules/glaze/api/std/vector.ixx +) + +# tuplet +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/tuplet/tuple.ixx +) + +# thread +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/thread/atomic.ixx + modules/glaze/thread/async.ixx + modules/glaze/thread/async_string.ixx + modules/glaze/thread/async_vector.ixx + modules/glaze/thread/shared_async_map.ixx + modules/glaze/thread/shared_async_vector.ixx + modules/glaze/thread/threadpool.ixx + modules/glaze/thread/value_proxy.ixx + modules/glaze/thread/guard.ixx +) + +# simd +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/simd/avx.ixx + modules/glaze/simd/neon.ixx + modules/glaze/simd/sse.ixx +) + +# reflection +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/reflection/to_tuple.ixx + modules/glaze/reflection/get_name.ixx + modules/glaze/reflection/requires_key.ixx +) + +# base64 +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/base64/base64.ixx +) + +# beve +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/beve/header.ixx + modules/glaze/beve/beve_to_json.ixx + modules/glaze/beve/key_traits.ixx + modules/glaze/beve/lazy.ixx + modules/glaze/beve/peek_header.ixx + modules/glaze/beve/ptr.ixx + modules/glaze/beve/read.ixx + modules/glaze/beve/size.ixx + modules/glaze/beve/skip.ixx + modules/glaze/beve/wrappers.ixx + modules/glaze/beve/write.ixx +) + +# file +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/file/file_ops.ixx + modules/glaze/file/hostname_include.ixx + modules/glaze/file/raw_or_file.ixx + modules/glaze/file/read_directory.ixx + modules/glaze/file/write_directory.ixx +) + +# cbor +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/cbor/cbor_to_json.ixx + modules/glaze/cbor/header.ixx + modules/glaze/cbor/read.ixx + modules/glaze/cbor/skip.ixx + modules/glaze/cbor/wrappers.ixx + modules/glaze/cbor/write.ixx +) + +# bson +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/bson/bson_to_json.ixx + modules/glaze/bson/header.ixx + modules/glaze/bson/read.ixx + modules/glaze/bson/skip.ixx + modules/glaze/bson/write.ixx +) + +# jsonb +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/jsonb/header.ixx + modules/glaze/jsonb/jsonb_to_json.ixx + modules/glaze/jsonb/read.ixx + modules/glaze/jsonb/skip.ixx + modules/glaze/jsonb/text_decode.ixx + modules/glaze/jsonb/write.ixx +) + +# containers +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/containers/flat_map.ixx + modules/glaze/containers/inplace_vector.ixx + modules/glaze/containers/ordered_small_map.ixx + modules/glaze/containers/ordered_map.ixx +) + +# hardware +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/hardware/volatile_array.ixx +) + +# record +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/record/recorder.ixx +) + +# trace +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/trace/trace.ixx +) + +# csv +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/csv/read.ixx + modules/glaze/csv/skip.ixx + modules/glaze/csv/write.ixx +) + +# exceptions +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/exceptions/binary_exceptions.ixx + modules/glaze/exceptions/cbor_exceptions.ixx + modules/glaze/exceptions/core_exceptions.ixx + modules/glaze/exceptions/csv_exceptions.ixx + modules/glaze/exceptions/json_exceptions.ixx + modules/glaze/exceptions/json_schema_exceptions.ixx + modules/glaze/exceptions/jsonb_exceptions.ixx + modules/glaze/exceptions/msgpack_exceptions.ixx +) + +# msgpack +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/msgpack/common.ixx + modules/glaze/msgpack/read.ixx + modules/glaze/msgpack/skip.ixx + modules/glaze/msgpack/write.ixx +) + +# ext (external) +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/ext/cli_menu.ixx + # modules/glaze/ext/eigen.ixx + modules/glaze/ext/jsonrpc.ixx +) + +# compare +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/compare/compare.ixx + modules/glaze/compare/approx.ixx +) + +# stencil +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/stencil/stencil.ixx + modules/glaze/stencil/stencilcount.ixx +) + +# format +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/format/format_to.ixx +) + +# toml +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/toml/common.ixx + modules/glaze/toml/opts.ixx + modules/glaze/toml/read.ixx + modules/glaze/toml/skip.ixx + modules/glaze/toml/write.ixx +) + +# hash +target_sources(glaze_glaze + PUBLIC + FILE_SET CXX_MODULES + FILES + modules/glaze/hash/sweethash.ixx +) diff --git a/docs/advanced-api-usage.md b/docs/advanced-api-usage.md index 2c748a1b17..70ea8b4136 100644 --- a/docs/advanced-api-usage.md +++ b/docs/advanced-api-usage.md @@ -36,12 +36,12 @@ struct custom_api : glz::api { return path == "/count"; } - bool read(const uint32_t format, const sv path, const sv data) noexcept override { + bool read(const std::uint32_t format, const sv path, const sv data) noexcept override { // Custom deserialization logic return true; } - bool write(const uint32_t format, const sv path, std::string& data) noexcept override { + bool write(const std::uint32_t format, const sv path, std::string& data) noexcept override { // Custom serialization logic return true; } @@ -454,30 +454,30 @@ Glaze generates type names following these rules: ```c++ // Fundamental types -glz::name_v // "int32_t" +glz::name_v // "std::int32_t" glz::name_v // "double" glz::name_v // "bool" // CV-qualifiers and references -glz::name_v // "const int32_t" -glz::name_v // "int32_t&" -glz::name_v // "const int32_t&" -glz::name_v // "int32_t&&" +glz::name_v // "const std::int32_t" +glz::name_v // "std::int32_t&" +glz::name_v // "const std::int32_t&" +glz::name_v // "std::int32_t&&" // Pointers -glz::name_v // "int32_t*" -glz::name_v // "const int32_t*" +glz::name_v // "std::int32_t*" +glz::name_v // "const std::int32_t*" // Containers -glz::name_v> // "std::vector" -glz::name_v> // "std::map" -glz::name_v> // "std::unordered_map" +glz::name_v> // "std::vector" +glz::name_v> // "std::map" +glz::name_v> // "std::unordered_map" // Functions -glz::name_v> // "std::function" +glz::name_v> // "std::function" glz::name_v> // "std::function" glz::name_v> - // "std::function" + // "std::function" ``` ### Debugging Type Mismatches diff --git a/docs/binary.md b/docs/binary.md index c953a2b40c..a35adddd43 100644 --- a/docs/binary.md +++ b/docs/binary.md @@ -41,7 +41,7 @@ The `glz::beve_size` function calculates the exact number of bytes needed to ser ```c++ my_struct s{}; -size_t size = glz::beve_size(s); +std::size_t size = glz::beve_size(s); // size contains the exact number of bytes needed to serialize s ``` @@ -51,14 +51,14 @@ size_t size = glz::beve_size(s); #include "glaze/beve.hpp" struct SensorData { - uint64_t timestamp; + std::uint64_t timestamp; double temperature; std::vector readings; }; // Calculate size before allocation SensorData data{12345, 98.6, {1.0, 2.0, 3.0}}; -size_t size = glz::beve_size(data); +std::size_t size = glz::beve_size(data); // Allocate shared memory with exact size void* shm = mmap(nullptr, size, PROT_READ | PROT_WRITE, @@ -75,8 +75,8 @@ For untagged serialization (structs written as arrays without keys), use `glz::b ```c++ my_struct s{}; -size_t tagged_size = glz::beve_size(s); // with keys -size_t untagged_size = glz::beve_size_untagged(s); // without keys (smaller) +std::size_t tagged_size = glz::beve_size(s); // with keys +std::size_t untagged_size = glz::beve_size_untagged(s); // without keys (smaller) ``` **Compressed Integer Size Helper** @@ -142,8 +142,8 @@ struct beve_header { uint8_t tag{}; // Raw tag byte uint8_t type{}; // Base type (see below) uint8_t ext_type{}; // For extensions: subtype (variant, complex, etc.) - size_t count{}; // Element count, string length, variant index, etc. - size_t header_size{}; // Bytes consumed by tag + count encoding + std::size_t count{}; // Element count, string length, variant index, etc. + std::size_t header_size{}; // Bytes consumed by tag + count encoding }; ``` @@ -200,7 +200,7 @@ if (!header) { } // Reject oversized arrays -constexpr size_t max_elements = 10000; +constexpr std::size_t max_elements = 10000; if (header->type == glz::tag::typed_array && header->count > max_elements) { return unexpected(error_code::invalid_length); } @@ -244,7 +244,7 @@ For C-style buffers: ```c++ const void* data = /* ... */; -size_t size = /* ... */; +std::size_t size = /* ... */; auto result = glz::beve_peek_header(data, size); ``` @@ -255,7 +255,7 @@ Use `glz::beve_peek_header_at` to peek at headers at arbitrary byte offsets with ```c++ std::string buffer = /* BEVE data */; -size_t offset = /* position to inspect */; +std::size_t offset = /* position to inspect */; auto header = glz::beve_peek_header_at(buffer, offset); if (header) { @@ -286,7 +286,7 @@ if (header) { ```c++ // Example: Multiple values in one buffer -int32_t val1 = 42; +std::int32_t val1 = 42; std::string val2 = "hello"; auto buffer1 = glz::write_beve(val1).value(); @@ -492,7 +492,7 @@ BEVE can serialize map-like containers whose key types expose a value through Gl ```c++ struct ModuleID { - uint64_t value{}; + std::uint64_t value{}; auto operator<=>(const ModuleID&) const = default; }; @@ -507,14 +507,14 @@ std::string beve{}; glz::write_beve(modules, beve); ``` -Glaze inspects the metadata, reuses the underlying `uint64_t`, and emits the numeric BEVE map header so the payload decodes as a regular number key. The same behaviour works for `std::unordered_map` and concatenated ranges such as `std::vector>`. +Glaze inspects the metadata, reuses the underlying `std::uint64_t`, and emits the numeric BEVE map header so the payload decodes as a regular number key. The same behaviour works for `std::unordered_map` and concatenated ranges such as `std::vector>`. If you prefer to keep a custom conversion in your metadata, `glz::cast` works as well: ```c++ template <> struct glz::meta { - static constexpr auto value = glz::cast<&ModuleID::value, uint64_t>; + static constexpr auto value = glz::cast<&ModuleID::value, std::uint64_t>; }; ``` @@ -641,7 +641,7 @@ For manual control over reading, use `read_beve_at` which returns the number of ```c++ std::string buffer = /* delimited BEVE data */; -size_t offset = 0; +std::size_t offset = 0; while (offset < buffer.size()) { my_struct obj{}; @@ -666,7 +666,7 @@ The standard `read_beve` function tracks bytes consumed via `ec.count`: my_struct obj{}; auto ec = glz::read_beve(obj, buffer); if (!ec) { - size_t bytes_consumed = ec.count; // Number of bytes read on success + std::size_t bytes_consumed = ec.count; // Number of bytes read on success } ``` @@ -716,7 +716,7 @@ if (result) { auto age = (*result)["user"]["age"].get(); // Check container size without parsing elements - size_t count = (*result)["items"].size(); + std::size_t count = (*result)["items"].size(); } ``` diff --git a/docs/cbor.md b/docs/cbor.md index eb9b4eed72..ff876de684 100644 --- a/docs/cbor.md +++ b/docs/cbor.md @@ -77,11 +77,11 @@ glz::write_cbor(values, buffer); // Uses typed array with bulk memcpy |------|-------------------|----------------| | `uint8_t` | 64 | 64 | | `uint16_t` | 69 | 65 | -| `uint32_t` | 70 | 66 | -| `uint64_t` | 71 | 67 | +| `std::uint32_t` | 70 | 66 | +| `std::uint64_t` | 71 | 67 | | `int8_t` | 72 | 72 | | `int16_t` | 77 | 73 | -| `int32_t` | 78 | 74 | +| `std::int32_t` | 78 | 74 | | `int64_t` | 79 | 75 | | `float` | 85 | 81 | | `double` | 86 | 82 | diff --git a/docs/custom-serialization.md b/docs/custom-serialization.md index 37f2ebdae2..b82e242316 100644 --- a/docs/custom-serialization.md +++ b/docs/custom-serialization.md @@ -12,7 +12,7 @@ Example: ```c++ struct date { - uint64_t data; + std::uint64_t data; std::string human_readable; }; diff --git a/docs/design/json_merge_patch_rfc7386.md b/docs/design/json_merge_patch_rfc7386.md index 711d742374..4e766d3693 100644 --- a/docs/design/json_merge_patch_rfc7386.md +++ b/docs/design/json_merge_patch_rfc7386.md @@ -163,7 +163,7 @@ namespace glz::detail inline error_ctx apply_merge_patch_impl( generic& target, const generic& patch, - uint32_t depth = 0 + std::uint32_t depth = 0 ) { if (depth >= max_recursive_depth_limit) [[unlikely]] { @@ -462,7 +462,7 @@ If the patch is not an object, it replaces the entire document: patch.data = glz::generic::object_t{}; glz::generic* current = &patch; - for (size_t i = 0; i < glz::max_recursive_depth_limit + 10; ++i) { + for (std::size_t i = 0; i < glz::max_recursive_depth_limit + 10; ++i) { current->get_object()["nested"].data = glz::generic::object_t{}; current = ¤t->get_object()["nested"]; } diff --git a/docs/design/json_patch_rfc6902.md b/docs/design/json_patch_rfc6902.md index 0e3f353c65..f69c51f09c 100644 --- a/docs/design/json_patch_rfc6902.md +++ b/docs/design/json_patch_rfc6902.md @@ -239,7 +239,7 @@ inline expected unescape_json_ptr(std::string_view token { std::string result; result.reserve(token.size()); - for (size_t i = 0; i < token.size(); ++i) { + for (std::size_t i = 0; i < token.size(); ++i) { if (token[i] == '~') { if (i + 1 >= token.size()) { return unexpected(error_ctx{error_code::invalid_json_pointer}); @@ -311,7 +311,7 @@ error_ctx patch(generic& document, const patch_document& ops, patch_opts opts) // Deep copy for rollback - requires O(n) space generic backup = document; - for (size_t i = 0; i < ops.size(); ++i) { + for (std::size_t i = 0; i < ops.size(); ++i) { auto ec = apply_operation(document, ops[i], opts); if (ec) { document = std::move(backup); // Rollback @@ -321,7 +321,7 @@ error_ctx patch(generic& document, const patch_document& ops, patch_opts opts) } } else { - for (size_t i = 0; i < ops.size(); ++i) { + for (std::size_t i = 0; i < ops.size(); ++i) { auto ec = apply_operation(document, ops[i], opts); if (ec) { ec.operation_index = i; @@ -367,7 +367,7 @@ namespace glz New error codes to add to `error_code` enum: ```cpp -enum struct error_code : uint32_t { +enum struct error_code : std::uint32_t { // ... existing codes ... // JSON Pointer errors diff --git a/docs/generic-json.md b/docs/generic-json.md index 022f26e451..4e52c2470f 100644 --- a/docs/generic-json.md +++ b/docs/generic-json.md @@ -62,16 +62,16 @@ assert(json["id"].as() == 9007199254740993.0); ### glz::generic_u64 -Provides full integer range support. Positive integers are stored as `uint64_t`, negative integers as `int64_t`, and floating-point numbers as `double`. This handles the complete unsigned 64-bit range (0 to 18.4 quintillion). +Provides full integer range support. Positive integers are stored as `std::uint64_t`, negative integers as `int64_t`, and floating-point numbers as `double`. This handles the complete unsigned 64-bit range (0 to 18.4 quintillion). ```c++ glz::generic_u64 json{}; std::string buffer = R"({"big_id": 18446744073709551615, "neg": -100, "pi": 3.14})"; glz::read_json(json, buffer); -// Maximum uint64_t value preserved exactly +// Maximum std::uint64_t value preserved exactly assert(json["big_id"].is_uint64()); -assert(json["big_id"].get() == 18446744073709551615ULL); +assert(json["big_id"].get() == 18446744073709551615ULL); // Negative integers stored as int64_t assert(json["neg"].is_int64()); @@ -161,7 +161,7 @@ There are also free functions of these, such as `glz::is_object(...)` - `.is_int64()` - true if stored as `int64_t` - `.is_double()` - true if stored as `double` -- `.is_uint64()` - true if stored as `uint64_t` (only `generic_u64`) +- `.is_uint64()` - true if stored as `std::uint64_t` (only `generic_u64`) - `.as_number()` - returns the value as `double`, converting if necessary ```c++ diff --git a/docs/glaze-interfaces.md b/docs/glaze-interfaces.md index 05c722128a..0b619ca8c1 100644 --- a/docs/glaze-interfaces.md +++ b/docs/glaze-interfaces.md @@ -47,10 +47,10 @@ namespace glz { [[nodiscard]] virtual bool contains(const sv path) noexcept = 0; // Read data into the API object from JSON or BEVE - virtual bool read(const uint32_t format, const sv path, const sv data) noexcept = 0; + virtual bool read(const std::uint32_t format, const sv path, const sv data) noexcept = 0; // Write data from the API object to JSON or BEVE - virtual bool write(const uint32_t format, const sv path, std::string& data) noexcept = 0; + virtual bool write(const std::uint32_t format, const sv path, std::string& data) noexcept = 0; // Get the last error message [[nodiscard]] virtual const sv last_error() const noexcept { return error; } diff --git a/docs/index.md b/docs/index.md index 9f993d5bb0..1ae1cd7459 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,7 +23,7 @@ struct my_struct { int i = 287; double d = 3.14; std::string hello = "Hello World"; - std::array arr = {1, 2, 3}; + std::array arr = {1, 2, 3}; }; // Write JSON diff --git a/docs/installation.md b/docs/installation.md index 9c274de113..a8545e4596 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,14 +1,14 @@ # Glaze Installation Guide -This guide covers some of the ways to install and integrate the Glaze JSON library into your C++ project. There are lots of packaged versions of Glaze, from [homebrew](https://formulae.brew.sh/formula/glaze) to [Conan](https://conan.io/center/recipes/glaze). +This guide covers some of the ways to install and integrate the Glaze JSON library into your C++ project. There are lots of packaged versions of Glaze, from [homebrew](https://formulae.brew.sh/formula/glaze) to [Conan](https://conan.io/center/recipes/glaze) and [vcpkg](https://vcpkg.io/en/package/glaze). ## System Requirements ### Compiler Support - **C++23** standard required -- **Clang 17+** +- **Clang 18+** - **GCC 13+** -- **MSVC 2022+** +- **Visual Studio 2026 MSVC Build Tools 14.51 and above** - **Apple Clang (latest Xcode)** ### Platform Support @@ -25,7 +25,7 @@ cl /Zc:preprocessor your_source.cpp ## Installation Methods -### 1. CMake FetchContent (Recommended) +### CMake FetchContent (Recommended) Add the following to your `CMakeLists.txt`: @@ -52,12 +52,30 @@ For production use, it's recommended to pin to a specific version: FetchContent_Declare( glaze GIT_REPOSITORY https://github.com/stephenberry/glaze.git - GIT_TAG v5.0.0 # Replace with desired version + GIT_TAG v7.4.0 # Replace with desired version GIT_SHALLOW TRUE ) ``` -### 2. Conan Package Manager +### Vcpkg Package Manager + +Glaze is available in [vcpkg](https://vcpkg.io/en/package/glaze). To learn more about vcpkg see https://learn.microsoft.com/en-us/vcpkg/get_started/get-started-vs?pivots=shell-powershell. + +To add Glaze to vcpkg project's dependencies, use: +``` +vcpkg add port glaze +``` +and add the following to your CMake file: +```cmake +find_package(glaze CONFIG REQUIRED) +# or find_package(glaze 7.4.0 CONFIG REQUIRED) if you wish to set minimum version number + +target_link_libraries(TPP PRIVATE glaze::glaze) +``` + +This makes the latest version of Glaze available for use. To update to the latest available version, go to the [vcpkg repository](https://github.com/microsoft/vcpkg), copy hash of the most recent commit and change the value in `vcpkg-configuration.json`. + +### Conan Package Manager Glaze is available in [Conan Center](https://conan.io/center/recipes/glaze). @@ -84,7 +102,7 @@ cmake --preset conan-default cmake --build --preset conan-release ``` -### 3. build2 Package Manager +### build2 Package Manager Glaze is available on [cppget](https://cppget.org/libglaze). @@ -99,7 +117,7 @@ import libs = libglaze%lib{glaze} exe{myapp}: cxx{main} $libs ``` -### 4. Linux Package Managers +### Linux Package Managers #### Arch Linux ```bash @@ -124,7 +142,7 @@ cmake .. sudo make install ``` -### 5. Manual Installation +### Manual Installation #### Download and Extract ```bash diff --git a/docs/json-pointer-syntax.md b/docs/json-pointer-syntax.md index 7003f6de15..9dae8e8676 100644 --- a/docs/json-pointer-syntax.md +++ b/docs/json-pointer-syntax.md @@ -108,7 +108,7 @@ This is useful for dynamic path construction: std::string buffer = R"({"users":[{"name":"Alice"},{"name":"Bob"}]})"; // Update user at runtime-determined index -size_t user_index = 1; +std::size_t user_index = 1; std::string path = "/users/" + std::to_string(user_index) + "/name"; glz::write_at(path, R"("Charlie")", buffer); // buffer is now: {"users":[{"name":"Alice"},{"name":"Charlie"}]} diff --git a/docs/json.md b/docs/json.md index c4e115744a..b06235a745 100644 --- a/docs/json.md +++ b/docs/json.md @@ -204,7 +204,7 @@ Person person{}; auto ec = glz::read_json(person, buffer); if (!ec) { // Success: ec.count contains bytes consumed - size_t bytes_read = ec.count; + std::size_t bytes_read = ec.count; // Useful for reading multiple values from one buffer: std::string_view remaining = std::string_view(buffer).substr(bytes_read); diff --git a/docs/lazy-beve.md b/docs/lazy-beve.md index 5da805cf21..492f3db010 100644 --- a/docs/lazy-beve.md +++ b/docs/lazy-beve.md @@ -187,7 +187,7 @@ if (result) { auto indexed = result->root().index(); // Now enjoy O(1) operations: - size_t count = indexed.size(); // O(1) - no scanning + std::size_t count = indexed.size(); // O(1) - no scanning auto key500 = indexed["key500"]; // Linear search in indexed keys auto first = indexed[0]; // O(1) - direct access by position @@ -214,7 +214,7 @@ if (result) { auto indexed = doc["items"].index(); // O(1) size query -size_t count = indexed.size(); +std::size_t count = indexed.size(); // O(1) empty check if (!indexed.empty()) { /* ... */ } @@ -317,8 +317,8 @@ if (value) { | Type | Description | |------|-------------| | `bool` | Boolean values | -| `int32_t`, `int64_t` | Signed integers | -| `uint32_t`, `uint64_t` | Unsigned integers | +| `std::int32_t`, `int64_t` | Signed integers | +| `std::uint32_t`, `std::uint64_t` | Unsigned integers | | `float`, `double` | Floating-point numbers | | `std::string` | String value | | `std::string_view` | String view (zero-copy) | @@ -364,7 +364,7 @@ auto arr = doc["items"]; if (arr.empty()) { /* ... */ } // Get number of elements (O(1) in BEVE - count is stored) -size_t count = arr.size(); +std::size_t count = arr.size(); // Check if object contains a key if (doc.root().contains("name")) { /* ... */ } @@ -389,7 +389,7 @@ if (result) { } // Also works with index access - size_t first_name_len = result->size[0]; // For arrays + std::size_t first_name_len = result->size[0]; // For arrays } ``` diff --git a/docs/lazy-json.md b/docs/lazy-json.md index 26dd583f06..d65d05f3a2 100644 --- a/docs/lazy-json.md +++ b/docs/lazy-json.md @@ -160,7 +160,7 @@ if (result) { auto users = (*result)["users"].index(); // Now enjoy O(1) operations: - size_t count = users.size(); // O(1) - no scanning + std::size_t count = users.size(); // O(1) - no scanning auto user500 = users[500]; // O(1) - direct access auto user999 = users[999]; // O(1) - no matter the position @@ -187,7 +187,7 @@ if (result) { auto indexed = doc["items"].index(); // O(1) size query -size_t count = indexed.size(); +std::size_t count = indexed.size(); // O(1) empty check if (!indexed.empty()) { /* ... */ } @@ -468,8 +468,8 @@ if (value) { | Type | Description | |------|-------------| | `bool` | Boolean values | -| `int32_t`, `int64_t` | Signed integers | -| `uint32_t`, `uint64_t` | Unsigned integers | +| `std::int32_t`, `int64_t` | Signed integers | +| `std::uint32_t`, `std::uint64_t` | Unsigned integers | | `float`, `double` | Floating-point numbers | | `std::string` | String with escape processing | | `std::string_view` | Raw string view (no escape processing) | @@ -515,7 +515,7 @@ auto arr = doc["items"]; if (arr.empty()) { /* ... */ } // Get number of elements (requires scanning) -size_t count = arr.size(); +std::size_t count = arr.size(); // Check if object contains a key if (doc.root().contains("name")) { /* ... */ } diff --git a/docs/modify-reflection.md b/docs/modify-reflection.md index bbb50cb00c..31b65f4e99 100644 --- a/docs/modify-reflection.md +++ b/docs/modify-reflection.md @@ -53,7 +53,7 @@ struct server_status { std::string name; // pure reflection keeps this key std::string region; // …and this one - uint64_t active_sessions; // and all the others + std::uint64_t active_sessions; // and all the others std::optional maintenance; double cpu_percent{}; }; diff --git a/docs/networking/advanced-networking.md b/docs/networking/advanced-networking.md index 29a21a3f88..319d474103 100644 --- a/docs/networking/advanced-networking.md +++ b/docs/networking/advanced-networking.md @@ -328,10 +328,10 @@ void run_multiple_servers_shared_context() { // Run the shared io_context in a thread pool std::vector threads; - const size_t num_threads = std::thread::hardware_concurrency(); + const std::size_t num_threads = std::thread::hardware_concurrency(); threads.reserve(num_threads); - for (size_t i = 0; i < num_threads; ++i) { + for (std::size_t i = 0; i < num_threads; ++i) { threads.emplace_back([io_ctx]() { io_ctx->run(); }); diff --git a/docs/networking/http-router.md b/docs/networking/http-router.md index cf4c1d881f..062629740a 100644 --- a/docs/networking/http-router.md +++ b/docs/networking/http-router.md @@ -184,7 +184,7 @@ glz::param_constraint hex_color{ .description = "Valid hex color code", .validation = [](std::string_view value) { if (value.size() != 7 || value[0] != '#') return false; - for (size_t i = 1; i < value.size(); ++i) { + for (std::size_t i = 1; i < value.size(); ++i) { if (!std::isxdigit(value[i])) return false; } return true; diff --git a/docs/networking/http-server.md b/docs/networking/http-server.md index c6cf9a7428..f533217f29 100644 --- a/docs/networking/http-server.md +++ b/docs/networking/http-server.md @@ -427,8 +427,8 @@ server.wrap([](const glz::request& req, glz::response& res, const auto& next) { **Request/Response Timing:** ```cpp struct Metrics { - std::atomic total_requests{0}; - std::atomic total_responses{0}; + std::atomic total_requests{0}; + std::atomic total_responses{0}; std::atomic response_time_sum{0.0}; }; diff --git a/docs/networking/websocket-client.md b/docs/networking/websocket-client.md index 974399b1d8..8cfc07931e 100644 --- a/docs/networking/websocket-client.md +++ b/docs/networking/websocket-client.md @@ -172,7 +172,7 @@ if (client.context()->stopped()) { Sets the maximum allowed message size in bytes. ```cpp -void set_max_message_size(size_t size); +void set_max_message_size(std::size_t size); ``` Default is 16 MB (16 * 1024 * 1024 bytes). @@ -566,7 +566,7 @@ int main() { // Process binary data const uint8_t* data = reinterpret_cast(message.data()); - for (size_t i = 0; i < std::min(size_t(16), message.size()); ++i) { + for (std::size_t i = 0; i < std::min(std::size_t(16), message.size()); ++i) { printf("%02X ", data[i]); } std::cout << std::endl; @@ -633,7 +633,7 @@ int main() { // Run the shared io_context in a thread pool std::vector threads; - for (size_t i = 0; i < std::thread::hardware_concurrency(); ++i) { + for (std::size_t i = 0; i < std::thread::hardware_concurrency(); ++i) { threads.emplace_back([io_ctx]() { io_ctx->run(); }); diff --git a/docs/options.md b/docs/options.md index 644b80bcce..e6eeef6719 100644 --- a/docs/options.md +++ b/docs/options.md @@ -14,7 +14,7 @@ The tables below list **all** compile time options, organized by category: | Option | Default | Description | |--------|---------|-------------| -| `uint32_t format` | `JSON` | Format selector (`JSON`, `BEVE`, `CSV`, `TOML`, etc.) | +| `std::uint32_t format` | `JSON` | Format selector (`JSON`, `BEVE`, `CSV`, `TOML`, etc.) | | `bool null_terminated` | `true` | Whether the input buffer is null terminated | | `bool comments` | `false` | Support reading JSONC style comments | | `bool error_on_unknown_keys` | `true` | Error when an unknown key is encountered | @@ -71,7 +71,7 @@ For CSV format, use `glz::opts_csv` which provides CSV-specific defaults. | Option | Default | Description | |--------|---------|-------------| -| `uint32_t format` | `CSV` | Format selector (fixed to CSV) | +| `std::uint32_t format` | `CSV` | Format selector (fixed to CSV) | | `bool null_terminated` | `true` | Whether the input buffer is null terminated | | `uint8_t layout` | `rowwise` | Data layout: `rowwise` or `colwise` | | `bool use_headers` | `true` | Read/write with column headers | diff --git a/docs/partial-read.md b/docs/partial-read.md index 65cd62c700..1a69a7e4ad 100644 --- a/docs/partial-read.md +++ b/docs/partial-read.md @@ -53,7 +53,7 @@ Example: read only the fields present in a struct and then short circuit the par struct partial_struct { std::string string{}; - int32_t integer{}; + std::int32_t integer{}; }; ``` diff --git a/docs/partial-write.md b/docs/partial-write.md index d80e9133ba..782b8da0f4 100644 --- a/docs/partial-write.md +++ b/docs/partial-write.md @@ -151,7 +151,7 @@ Three overloads are available: error_ctx write_json_partial(T&& value, const Keys& keys, Buffer&& buffer); // 2. Write to raw buffer (char*) -expected write_json_partial(T&& value, const Keys& keys, Buffer&& buffer); +expected write_json_partial(T&& value, const Keys& keys, Buffer&& buffer); // 3. Return a new string expected write_json_partial(T&& value, const Keys& keys); @@ -293,7 +293,7 @@ Three overloads are available: error_ctx write_json_exclude(T&& value, const Keys& exclude_keys, Buffer&& buffer); // 2. Write to raw buffer (char*) -expected write_json_exclude(T&& value, const Keys& exclude_keys, Buffer&& buffer); +expected write_json_exclude(T&& value, const Keys& exclude_keys, Buffer&& buffer); // 3. Return a new string expected write_json_exclude(T&& value, const Keys& exclude_keys); diff --git a/docs/reading.md b/docs/reading.md index 6b035c6e1b..97a8286a94 100644 --- a/docs/reading.md +++ b/docs/reading.md @@ -8,7 +8,7 @@ All read functions return `glz::error_ctx`: ```cpp struct error_ctx { - size_t count{}; // Bytes consumed from input + std::size_t count{}; // Bytes consumed from input error_code ec{}; // Error code (none on success) std::string_view custom_error_message{}; // Optional error details @@ -59,7 +59,7 @@ my_struct obj1{}, obj2{}; auto ec = glz::read_json(obj1, input); if (!ec) { - size_t consumed = ec.count; // Bytes consumed by first read + std::size_t consumed = ec.count; // Bytes consumed by first read // Read second object from remaining buffer ec = glz::read_json(obj2, std::string_view(input).substr(consumed)); diff --git a/docs/rename-keys.md b/docs/rename-keys.md index e4cfdca764..fb562fa879 100644 --- a/docs/rename-keys.md +++ b/docs/rename-keys.md @@ -220,7 +220,7 @@ struct AppContext { template <> struct glz::meta { - template + template static constexpr auto rename_key() { using MemberType = glz::member_type_t; @@ -248,13 +248,13 @@ You can customize how type names are formatted by manipulating them at compile t ```cpp template <> struct glz::meta { - template + template static constexpr auto rename_key() { using MemberType = glz::member_type_t; if constexpr (std::is_enum_v) { constexpr auto full_name = glz::name_v; - constexpr size_t pos = full_name.rfind("::"); + constexpr std::size_t pos = full_name.rfind("::"); return (pos == std::string_view::npos) ? full_name : full_name.substr(pos + 2); @@ -286,7 +286,7 @@ struct MixedTypes { template <> struct glz::meta { - template + template static constexpr auto rename_key() { using MemberType = glz::member_type_t; constexpr auto name = glz::member_nameof; @@ -314,7 +314,7 @@ struct Point { template <> struct glz::meta { - template + template static constexpr auto rename_key() { constexpr auto name = glz::member_nameof; @@ -346,7 +346,7 @@ std::string json = glz::write_json(p).value(); | Variant | Use When | |---------|----------| | `rename_key(const std::string_view key)` | You need to transform keys based on their string values | -| `template rename_key()` | You need access to member types or index information | +| `template rename_key()` | You need access to member types or index information | | Built-in transformers (e.g., `glz::camel_case`) | You want simple naming convention conversions | ### Implementation Notes diff --git a/docs/rpc/repe-buffer.md b/docs/rpc/repe-buffer.md index 2c2dabed80..23a153ff9b 100644 --- a/docs/rpc/repe-buffer.md +++ b/docs/rpc/repe-buffer.md @@ -145,7 +145,7 @@ The function validates: Overloads: ```cpp // From raw pointer + size -glz::error_code from_buffer(const char* data, size_t size, message& msg); +glz::error_code from_buffer(const char* data, std::size_t size, message& msg); // From string_view glz::error_code from_buffer(std::string_view data, message& msg); @@ -165,7 +165,7 @@ struct request_view { std::string_view query; // View into original buffer std::string_view body; // View into original buffer - [[nodiscard]] uint64_t id() const noexcept; + [[nodiscard]] std::uint64_t id() const noexcept; [[nodiscard]] bool is_notify() const noexcept; [[nodiscard]] error_code error() const noexcept; }; @@ -352,7 +352,7 @@ Returns an empty `string_view` on error (invalid header, truncated data). ```cpp #include "glaze/rpc/repe/buffer.hpp" -void route_message(const char* data, size_t size) { +void route_message(const char* data, std::size_t size) { // Extract query without full deserialization auto query = glz::repe::extract_query(data, size); diff --git a/docs/rpc/repe-jsonrpc-conversion.md b/docs/rpc/repe-jsonrpc-conversion.md index 6b323cec39..0c622c7fdc 100644 --- a/docs/rpc/repe-jsonrpc-conversion.md +++ b/docs/rpc/repe-jsonrpc-conversion.md @@ -146,7 +146,7 @@ std::string jsonrpc = repe::to_jsonrpc_request(notification); ### ID Handling -REPE uses `uint64_t` for IDs, while JSON-RPC supports strings, numbers, or null: +REPE uses `std::uint64_t` for IDs, while JSON-RPC supports strings, numbers, or null: - Numeric IDs are directly mapped between protocols - Numeric strings (e.g., `"123"`) are parsed as numbers diff --git a/docs/rpc/repe-plugin.md b/docs/rpc/repe-plugin.md index 6c60c24040..5956d271e3 100644 --- a/docs/rpc/repe-plugin.md +++ b/docs/rpc/repe-plugin.md @@ -42,7 +42,7 @@ Plugins and hosts should check version compatibility before use. When the plugin // ABI-stable buffer for request/response data typedef struct repe_buffer { const char* data; - uint64_t size; + std::uint64_t size; } repe_buffer; // Result codes for plugin operations @@ -66,13 +66,13 @@ Plugins must export these symbols with C linkage: ```c // Interface version for compatibility checking (standalone for ABI safety) -uint32_t repe_plugin_interface_version(void); +std::uint32_t repe_plugin_interface_version(void); // Plugin metadata (returns pointer to static struct) const repe_plugin_data* repe_plugin_info(void); // Request processing -repe_buffer repe_plugin_call(const char* request, uint64_t request_size); +repe_buffer repe_plugin_call(const char* request, std::uint64_t request_size); ``` The `repe_plugin_info()` function must return a pointer that remains valid for the plugin's entire lifetime. The recommended pattern is to use a file-scope static: @@ -124,7 +124,7 @@ namespace glz::repe { void plugin_error_response( error_code ec, std::string_view error_msg, - uint64_t id = 0 + std::uint64_t id = 0 ); } ``` @@ -146,7 +146,7 @@ namespace glz::repe { repe_buffer plugin_call( Registry& registry, const char* request, - uint64_t request_size + std::uint64_t request_size ); } ``` @@ -217,7 +217,7 @@ static const repe_plugin_data plugin_info = { // Plugin exports with C linkage extern "C" { // Required: Interface version for ABI compatibility - uint32_t repe_plugin_interface_version() { + std::uint32_t repe_plugin_interface_version() { return REPE_PLUGIN_INTERFACE_VERSION; } @@ -243,7 +243,7 @@ extern "C" { } // Required: Request processing - repe_buffer repe_plugin_call(const char* request, uint64_t request_size) { + repe_buffer repe_plugin_call(const char* request, std::uint64_t request_size) { ensure_initialized(); // Plugin ensures initialization before dispatch return glz::repe::plugin_call(internal_registry, request, request_size); } @@ -267,11 +267,11 @@ struct loaded_plugin { void* handle = nullptr; // Function pointers - uint32_t (*interface_version_fn)(void) = nullptr; + std::uint32_t (*interface_version_fn)(void) = nullptr; const repe_plugin_data* (*info_fn)(void) = nullptr; repe_result (*init_fn)(void) = nullptr; void (*shutdown_fn)(void) = nullptr; - repe_buffer (*call_fn)(const char*, uint64_t) = nullptr; + repe_buffer (*call_fn)(const char*, std::uint64_t) = nullptr; ~loaded_plugin() { if (handle) { @@ -280,7 +280,7 @@ struct loaded_plugin { } } - repe_buffer call(const char* req, uint64_t size) const { + repe_buffer call(const char* req, std::uint64_t size) const { return call_fn(req, size); } }; @@ -295,11 +295,11 @@ std::optional load_plugin(const std::string& path) { // Load required symbols plugin.interface_version_fn = - (uint32_t(*)(void))dlsym(plugin.handle, "repe_plugin_interface_version"); + (std::uint32_t(*)(void))dlsym(plugin.handle, "repe_plugin_interface_version"); plugin.info_fn = (const repe_plugin_data*(*)(void))dlsym(plugin.handle, "repe_plugin_info"); plugin.call_fn = - (repe_buffer(*)(const char*, uint64_t))dlsym(plugin.handle, "repe_plugin_call"); + (repe_buffer(*)(const char*, std::uint64_t))dlsym(plugin.handle, "repe_plugin_call"); // Load optional symbols (may be NULL) plugin.init_fn = @@ -437,7 +437,7 @@ See [REPE RPC](repe-rpc.md) for more details on thread-safe classes. | Symbol | Required | Description | |--------|----------|-------------| | `REPE_PLUGIN_INTERFACE_VERSION` | - | Macro defining current interface version (3) | -| `repe_buffer` | - | POD struct: `{const char* data, uint64_t size}` | +| `repe_buffer` | - | POD struct: `{const char* data, std::uint64_t size}` | | `repe_result` | - | Enum: `REPE_OK`, `REPE_ERROR_*` | | `repe_plugin_data` | - | Struct: `{name, version, root_path}` | | `repe_plugin_interface_version()` | Yes | Returns interface version (standalone for ABI safety) | diff --git a/docs/security.md b/docs/security.md index 0ed533e338..4060490c86 100644 --- a/docs/security.md +++ b/docs/security.md @@ -57,9 +57,9 @@ Apply limits to all strings/arrays in a parse operation: // Define custom options with allocation limits struct secure_opts : glz::opts { - uint32_t format = glz::BEVE; - size_t max_string_length = 1024; // Max 1KB per string - size_t max_array_size = 10000; // Max 10,000 elements per array + std::uint32_t format = glz::BEVE; + std::size_t max_string_length = 1024; // Max 1KB per string + std::size_t max_array_size = 10000; // Max 10,000 elements per array }; std::vector data; @@ -107,9 +107,9 @@ For applications that need to set limits dynamically at runtime (e.g., based on ```cpp struct secure_context : glz::context { - size_t max_string_length = 0; // 0 = no limit - size_t max_array_size = 0; - size_t max_map_size = 0; + std::size_t max_string_length = 0; // 0 = no limit + std::size_t max_array_size = 0; + std::size_t max_map_size = 0; }; // Set limits dynamically based on user tier @@ -143,7 +143,7 @@ Both mechanisms can be used together—either can reject a value that exceeds it 1. **Limit input buffer size**: Control the maximum message size your application accepts at the network layer, before passing data to Glaze. ```cpp -constexpr size_t MAX_MESSAGE_SIZE = 1024 * 1024; // 1 MB limit +constexpr std::size_t MAX_MESSAGE_SIZE = 1024 * 1024; // 1 MB limit void handle_message(const std::span data) { if (data.size() > MAX_MESSAGE_SIZE) { diff --git a/docs/stencil-mustache.md b/docs/stencil-mustache.md index e546202a91..b251cd29ed 100644 --- a/docs/stencil-mustache.md +++ b/docs/stencil-mustache.md @@ -9,7 +9,7 @@ struct person { std::string first_name{}; std::string last_name{}; - uint32_t age{}; + std::uint32_t age{}; bool hungry{}; bool employed{}; }; @@ -69,7 +69,7 @@ struct TodoItem { std::string text; bool completed; std::string priority; - size_t id; + std::size_t id; }; struct TodoList { diff --git a/docs/thread-pool.md b/docs/thread-pool.md index afa2298ed2..d9f0cf40fe 100644 --- a/docs/thread-pool.md +++ b/docs/thread-pool.md @@ -22,11 +22,11 @@ The example below shows how results can be returned from a worker function and s glz::pool pool; auto f = [] { std::mt19937_64 generator{}; - std::uniform_int_distribution dist{ 0, 100 }; + std::uniform_int_distribution dist{ 0, 100 }; return dist(generator); }; -std::vector> numbers; +std::vector> numbers; for (auto i = 0; i < 1000; ++i) { numbers.emplace_back(pool.emplace_back(f)); } diff --git a/docs/toml.md b/docs/toml.md index 2e138e868e..ff5cb35c3c 100644 --- a/docs/toml.md +++ b/docs/toml.md @@ -546,7 +546,7 @@ The generic JSON types provide a convenient way to parse arbitrary TOML data: |------|-----------------|----------| | `glz::generic` | `double` | General purpose, preserves floating-point precision | | `glz::generic_i64` | `int64_t` | When integers must be preserved exactly | -| `glz::generic_u64` | `uint64_t` for positive, `int64_t` for negative | When large positive integers are needed | +| `glz::generic_u64` | `std::uint64_t` for positive, `int64_t` for negative | When large positive integers are needed | #### Using glz::generic @@ -591,10 +591,10 @@ Use `glz::generic_u64` when working with large unsigned integers: ```cpp glz::generic_u64 data; -glz::read_toml(data, "big = 18446744073709551615"); // Max uint64_t +glz::read_toml(data, "big = 18446744073709551615"); // Max std::uint64_t auto& obj = std::get(data); -auto& big = std::get(obj["big"]); // 18446744073709551615 +auto& big = std::get(obj["big"]); // 18446744073709551615 ``` Negative integers are stored as `int64_t` even in u64 mode: @@ -621,7 +621,7 @@ When reading into a variant or generic type, Glaze uses these rules to determine For integers in `glz::generic_u64` mode: - Numbers starting with `-` are stored as `int64_t` -- Positive numbers are stored as `uint64_t` +- Positive numbers are stored as `std::uint64_t` ### Writing Generic Types diff --git a/docs/variant-handling.md b/docs/variant-handling.md index 438b859171..df3ad56829 100644 --- a/docs/variant-handling.md +++ b/docs/variant-handling.md @@ -18,9 +18,9 @@ expect(s == R"("not_a_fish")"); Read example: ```c++ -std::variant x = 44; +std::variant x = 44; glz::read_json(x, "33"); -expect(std::get(x) == 33); +expect(std::get(x) == 33); ``` ### Multiple Types of Same Category diff --git a/docs/volatile-support.md b/docs/volatile-support.md index 6eb5b3bd45..de64d5772d 100644 --- a/docs/volatile-support.md +++ b/docs/volatile-support.md @@ -11,9 +11,9 @@ struct my_struct { glz::volatile_array a{}; bool b{}; - int32_t c{}; + std::int32_t c{}; double d{}; - uint32_t e{}; + std::uint32_t e{}; }; ``` diff --git a/docs/wrappers.md b/docs/wrappers.md index b0c85a5a45..661638bbc2 100644 --- a/docs/wrappers.md +++ b/docs/wrappers.md @@ -210,7 +210,7 @@ When reading, first reads a value as a string, which unescapes, and then reads t ```c++ struct client_state { - uint64_t id{}; + std::uint64_t id{}; std::map> layouts{}; }; @@ -792,9 +792,9 @@ For global limits (applying to all strings/arrays), use custom options instead: ```c++ struct secure_opts : glz::opts { - uint32_t format = glz::BEVE; - size_t max_string_length = 1024; // Max 1KB per string - size_t max_array_size = 10000; // Max 10,000 elements per array + std::uint32_t format = glz::BEVE; + std::size_t max_string_length = 1024; // Max 1KB per string + std::size_t max_array_size = 10000; // Max 10,000 elements per array }; auto ec = glz::read(obj, buffer); @@ -1021,13 +1021,13 @@ Calls custom read and write std::functions, lambdas, or member functions. ```c++ struct custom_encoding { - uint64_t x{}; + std::uint64_t x{}; std::string y{}; - std::array z{}; + std::array z{}; void read_x(const std::string& s) { x = std::stoi(s); } - uint64_t write_x() { return x; } + std::uint64_t write_x() { return x; } void read_y(const std::string& s) { y = "hello" + s; } @@ -1057,7 +1057,7 @@ In use: expect(!glz::read_json(obj, s)); expect(obj.x == 3); expect(obj.y == "helloworld"); - expect(obj.z == std::array{1, 2, 3}); + expect(obj.z == std::array{1, 2, 3}); }; "custom_writing"_test = [] { @@ -1261,7 +1261,7 @@ struct opts_skip_null_json : glz::opts { **BEVE:** ```c++ struct opts_skip_null_beve : glz::opts { - uint32_t format = glz::BEVE; + std::uint32_t format = glz::BEVE; bool skip_null_members_on_read = true; }; ``` diff --git a/docs/writing.md b/docs/writing.md index 1ba4ab6dc3..33bef8a61f 100644 --- a/docs/writing.md +++ b/docs/writing.md @@ -8,7 +8,7 @@ All write functions return `glz::error_ctx`: ```cpp struct error_ctx { - size_t count{}; // Bytes written to output + std::size_t count{}; // Bytes written to output error_code ec{}; // Error code (none on success) std::string_view custom_error_message{}; // Optional error details @@ -55,7 +55,7 @@ if (ec) { // Use a larger buffer or the string-returning overload: auto result = glz::write_json(obj); if (result) { - size_t required_size = result->size(); + std::size_t required_size = result->size(); } } return; @@ -116,7 +116,7 @@ if (ec.ec == glz::error_code::buffer_overflow) { // To get actual required size, use the string-returning overload: auto full = glz::write_json(large_object); if (full) { - size_t required = full->size(); + std::size_t required = full->size(); } } ``` @@ -188,20 +188,20 @@ Glaze uses a traits system that can be specialized for custom buffer types: ```cpp namespace glz { - template + template struct buffer_traits> { static constexpr bool is_resizable = false; static constexpr bool has_bounded_capacity = true; - static size_t capacity(const my_lib::ring_buffer& b) noexcept { + static std::size_t capacity(const my_lib::ring_buffer& b) noexcept { return b.available_write_space(); } - static bool ensure_capacity(my_lib::ring_buffer& b, size_t needed) noexcept { + static bool ensure_capacity(my_lib::ring_buffer& b, std::size_t needed) noexcept { return b.available_write_space() >= needed; } - static void finalize(my_lib::ring_buffer& b, size_t written) noexcept { + static void finalize(my_lib::ring_buffer& b, std::size_t written) noexcept { b.commit(written); } }; diff --git a/examples/wrapping_middleware_example.cpp b/examples/wrapping_middleware_example.cpp index 9da6d7fc07..38c791033e 100644 --- a/examples/wrapping_middleware_example.cpp +++ b/examples/wrapping_middleware_example.cpp @@ -11,6 +11,9 @@ #include "glaze/net/http_server.hpp" // Thread-safe metrics structure + +using std::uint64_t; + struct ServerMetrics { std::atomic total_requests{0}; diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index 2bceb19611..c54f0e76d8 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -15,7 +15,7 @@ set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer) check_source_compiles(CXX " #include #include - extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) + extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* Data, std::size_t Size) { return 0;} " haslibfuzzer) diff --git a/fuzzing/binary_reflection.cpp b/fuzzing/binary_reflection.cpp index 18ce8be20f..d67e9961f7 100644 --- a/fuzzing/binary_reflection.cpp +++ b/fuzzing/binary_reflection.cpp @@ -4,6 +4,9 @@ #include #include +using std::uint64_t; +using std::size_t; + struct my_struct { int i = 287; diff --git a/fuzzing/cbor_reflection.cpp b/fuzzing/cbor_reflection.cpp index 7a658ab5bb..94c6b7deaf 100644 --- a/fuzzing/cbor_reflection.cpp +++ b/fuzzing/cbor_reflection.cpp @@ -5,6 +5,9 @@ #include #include +using std::uint64_t; +using std::size_t; + struct my_struct { int i = 287; diff --git a/fuzzing/cbor_roundtrip_floating.cpp b/fuzzing/cbor_roundtrip_floating.cpp index 276e353431..d577eb0c34 100644 --- a/fuzzing/cbor_roundtrip_floating.cpp +++ b/fuzzing/cbor_roundtrip_floating.cpp @@ -8,6 +8,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/cbor_roundtrip_int.cpp b/fuzzing/cbor_roundtrip_int.cpp index 0b7618a7f4..cfc1eb5f3d 100644 --- a/fuzzing/cbor_roundtrip_int.cpp +++ b/fuzzing/cbor_roundtrip_int.cpp @@ -7,6 +7,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/cbor_roundtrip_string.cpp b/fuzzing/cbor_roundtrip_string.cpp index 1e02b5e695..57b1c075bf 100644 --- a/fuzzing/cbor_roundtrip_string.cpp +++ b/fuzzing/cbor_roundtrip_string.cpp @@ -6,6 +6,8 @@ #include #include +using std::size_t; + struct S { std::string value{}; diff --git a/fuzzing/csv_parsing.cpp b/fuzzing/csv_parsing.cpp index b9318ed92c..1b33e70943 100644 --- a/fuzzing/csv_parsing.cpp +++ b/fuzzing/csv_parsing.cpp @@ -4,6 +4,8 @@ #include #include +using std::size_t; + struct my_struct { std::vector num1{}; diff --git a/fuzzing/json_exhaustive_roundtrip_float.cpp b/fuzzing/json_exhaustive_roundtrip_float.cpp index 2ba4f84304..d1c5ae273d 100644 --- a/fuzzing/json_exhaustive_roundtrip_float.cpp +++ b/fuzzing/json_exhaustive_roundtrip_float.cpp @@ -9,6 +9,10 @@ #include // must be outside test(), compilation fails on gcc 13 otherwise + +using std::uint32_t; +using std::size_t; + struct Value { // use a short name to reduce the number of characters written @@ -17,7 +21,7 @@ struct Value void test() { - using UT = std::uint32_t; + using UT = uint32_t; static_assert(sizeof(float) == sizeof(UT)); auto test_one_value = [](const UT loopvar, auto& outbuf) { diff --git a/fuzzing/json_exhaustive_roundtrip_int.cpp b/fuzzing/json_exhaustive_roundtrip_int.cpp index 1ddc7d41d1..7b51d6bb7b 100644 --- a/fuzzing/json_exhaustive_roundtrip_int.cpp +++ b/fuzzing/json_exhaustive_roundtrip_int.cpp @@ -8,6 +8,13 @@ #include // must be outside test(), compilation fails on gcc 13 otherwise + +using std::int16_t; +using std::uint16_t; +using std::int32_t; +using std::uint32_t; +using std::size_t; + template struct Value { @@ -114,12 +121,12 @@ void testonetype(int bits) { switch (bits) { case 16: - test(); - test(); + test(); + test(); break; case 32: - test(); - test(); + test(); + test(); break; } } diff --git a/fuzzing/json_generic.cpp b/fuzzing/json_generic.cpp index 696949ae0e..ebbc66c945 100644 --- a/fuzzing/json_generic.cpp +++ b/fuzzing/json_generic.cpp @@ -3,6 +3,8 @@ #include #include +using std::size_t; + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // non-null terminated diff --git a/fuzzing/json_jmespath.cpp b/fuzzing/json_jmespath.cpp index ee9d27568c..f7221a4682 100644 --- a/fuzzing/json_jmespath.cpp +++ b/fuzzing/json_jmespath.cpp @@ -6,6 +6,8 @@ #include #include +using std::size_t; + struct Person { std::string first_name{}; @@ -16,7 +18,7 @@ struct Person namespace { template - void impl(const std::size_t pathsize, std::string_view all_buffer) + void impl(const size_t pathsize, std::string_view all_buffer) { // make separate allocations to make it easier for address sanitizer to catch // out of bounds access. also, make the size known up front so the allocation is diff --git a/fuzzing/json_minify.cpp b/fuzzing/json_minify.cpp index 2fd454165b..f3e33b9ad1 100644 --- a/fuzzing/json_minify.cpp +++ b/fuzzing/json_minify.cpp @@ -3,6 +3,8 @@ #include #include +using std::size_t; + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // use a vector with null termination instead of a std::string to avoid diff --git a/fuzzing/json_prettify.cpp b/fuzzing/json_prettify.cpp index a53c6a4627..9a7f37be60 100644 --- a/fuzzing/json_prettify.cpp +++ b/fuzzing/json_prettify.cpp @@ -3,6 +3,8 @@ #include #include +using std::size_t; + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // use a vector with null termination instead of a std::string to avoid diff --git a/fuzzing/json_reflection.cpp b/fuzzing/json_reflection.cpp index d9bc66c9a0..498335b3d0 100644 --- a/fuzzing/json_reflection.cpp +++ b/fuzzing/json_reflection.cpp @@ -4,6 +4,9 @@ #include #include +using std::uint64_t; +using std::size_t; + struct my_struct { int i = 287; diff --git a/fuzzing/json_roundtrip_floating.cpp b/fuzzing/json_roundtrip_floating.cpp index 540abe5632..ea3e69773e 100644 --- a/fuzzing/json_roundtrip_floating.cpp +++ b/fuzzing/json_roundtrip_floating.cpp @@ -7,6 +7,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/json_roundtrip_int.cpp b/fuzzing/json_roundtrip_int.cpp index 64f4a55c73..638d184c72 100644 --- a/fuzzing/json_roundtrip_int.cpp +++ b/fuzzing/json_roundtrip_int.cpp @@ -6,6 +6,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/json_roundtrip_string.cpp b/fuzzing/json_roundtrip_string.cpp index 89fbb33341..5ecbb69177 100644 --- a/fuzzing/json_roundtrip_string.cpp +++ b/fuzzing/json_roundtrip_string.cpp @@ -6,6 +6,8 @@ #include #include +using std::size_t; + struct S { std::string value{}; diff --git a/fuzzing/json_with_comments.cpp b/fuzzing/json_with_comments.cpp index 03563a8bc2..ea7351ffee 100644 --- a/fuzzing/json_with_comments.cpp +++ b/fuzzing/json_with_comments.cpp @@ -4,6 +4,9 @@ #include #include +using std::uint64_t; +using std::size_t; + struct my_struct { int i = 287; diff --git a/fuzzing/main.cpp b/fuzzing/main.cpp index 82ec8c0386..62c2b1ade2 100644 --- a/fuzzing/main.cpp +++ b/fuzzing/main.cpp @@ -11,6 +11,8 @@ * and feeding it to a program with this main function. */ +using std::size_t; + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size); void handle_file(std::filesystem::path file) diff --git a/fuzzing/msgpack_reflection.cpp b/fuzzing/msgpack_reflection.cpp index 9cfa203c19..73f52ed0d4 100644 --- a/fuzzing/msgpack_reflection.cpp +++ b/fuzzing/msgpack_reflection.cpp @@ -5,6 +5,9 @@ #include #include +using std::uint64_t; +using std::size_t; + struct my_struct { int i = 287; diff --git a/fuzzing/msgpack_roundtrip_floating.cpp b/fuzzing/msgpack_roundtrip_floating.cpp index 7f532f6296..1a8b0ed783 100644 --- a/fuzzing/msgpack_roundtrip_floating.cpp +++ b/fuzzing/msgpack_roundtrip_floating.cpp @@ -8,6 +8,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/msgpack_roundtrip_int.cpp b/fuzzing/msgpack_roundtrip_int.cpp index 6bbd26b139..bb3f0d4667 100644 --- a/fuzzing/msgpack_roundtrip_int.cpp +++ b/fuzzing/msgpack_roundtrip_int.cpp @@ -7,6 +7,9 @@ #include // must be outside test() to work in gcc<14 + +using std::size_t; + template struct Value { diff --git a/fuzzing/msgpack_roundtrip_string.cpp b/fuzzing/msgpack_roundtrip_string.cpp index c06d9616e5..8302d8bf50 100644 --- a/fuzzing/msgpack_roundtrip_string.cpp +++ b/fuzzing/msgpack_roundtrip_string.cpp @@ -6,6 +6,8 @@ #include #include +using std::size_t; + struct S { std::string value{}; diff --git a/include/glaze/api/std/deque.hpp b/include/glaze/api/std/deque.hpp deleted file mode 100644 index 5d30132ca2..0000000000 --- a/include/glaze/api/std/deque.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/list.hpp b/include/glaze/api/std/list.hpp deleted file mode 100644 index 842bb25b91..0000000000 --- a/include/glaze/api/std/list.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/map.hpp b/include/glaze/api/std/map.hpp deleted file mode 100644 index fe643e3fb8..0000000000 --- a/include/glaze/api/std/map.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = - join_v, name_v, chars<",">, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/optional.hpp b/include/glaze/api/std/optional.hpp deleted file mode 100644 index 219acba3ea..0000000000 --- a/include/glaze/api/std/optional.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/set.hpp b/include/glaze/api/std/set.hpp deleted file mode 100644 index 7a1fef65cf..0000000000 --- a/include/glaze/api/std/set.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/shared_ptr.hpp b/include/glaze/api/std/shared_ptr.hpp deleted file mode 100644 index 0029dfc46d..0000000000 --- a/include/glaze/api/std/shared_ptr.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/string.hpp b/include/glaze/api/std/string.hpp deleted file mode 100644 index 6dab83f468..0000000000 --- a/include/glaze/api/std/string.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template <> - struct meta - { - static constexpr std::string_view name = "std::string"; - }; -} diff --git a/include/glaze/api/std/tuple.hpp b/include/glaze/api/std/tuple.hpp deleted file mode 100644 index 28c3140a2c..0000000000 --- a/include/glaze/api/std/tuple.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = [](std::index_sequence) { - return join_v, - ((I != sizeof...(T) - 1) ? join_v, chars<",">> : join_v>)..., chars<">">>; - }(std::make_index_sequence{}); - }; -} diff --git a/include/glaze/api/std/unique_ptr.hpp b/include/glaze/api/std/unique_ptr.hpp deleted file mode 100644 index 616feb693f..0000000000 --- a/include/glaze/api/std/unique_ptr.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/unordered_map.hpp b/include/glaze/api/std/unordered_map.hpp deleted file mode 100644 index 0578f50b45..0000000000 --- a/include/glaze/api/std/unordered_map.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = - join_v, name_v, chars<",">, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/unordered_set.hpp b/include/glaze/api/std/unordered_set.hpp deleted file mode 100644 index 13b4bf6e7f..0000000000 --- a/include/glaze/api/std/unordered_set.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/api/std/vector.hpp b/include/glaze/api/std/vector.hpp deleted file mode 100644 index 1d5463655d..0000000000 --- a/include/glaze/api/std/vector.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/meta.hpp" - -namespace glz -{ - template - struct meta> - { - static constexpr std::string_view name = join_v, name_v, chars<">">>; - }; -} diff --git a/include/glaze/beve.hpp b/include/glaze/beve.hpp deleted file mode 100644 index 41dd825807..0000000000 --- a/include/glaze/beve.hpp +++ /dev/null @@ -1,15 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/beve/header.hpp" -#include "glaze/beve/lazy.hpp" -#include "glaze/beve/ptr.hpp" -#include "glaze/beve/read.hpp" -#include "glaze/beve/size.hpp" -#include "glaze/beve/wrappers.hpp" -#include "glaze/beve/write.hpp" -#include "glaze/core/as_array_wrapper.hpp" -#include "glaze/core/wrapper_traits.hpp" -#include "glaze/thread/atomic.hpp" diff --git a/include/glaze/bson.hpp b/include/glaze/bson.hpp deleted file mode 100644 index 920b3c051f..0000000000 --- a/include/glaze/bson.hpp +++ /dev/null @@ -1,10 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/bson/bson_to_json.hpp" -#include "glaze/bson/header.hpp" -#include "glaze/bson/read.hpp" -#include "glaze/bson/skip.hpp" -#include "glaze/bson/write.hpp" diff --git a/include/glaze/cbor.hpp b/include/glaze/cbor.hpp deleted file mode 100644 index edfabc0425..0000000000 --- a/include/glaze/cbor.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/cbor/cbor_to_json.hpp" -#include "glaze/cbor/header.hpp" -#include "glaze/cbor/read.hpp" -#include "glaze/cbor/wrappers.hpp" -#include "glaze/cbor/write.hpp" -#include "glaze/core/wrapper_traits.hpp" diff --git a/include/glaze/chrono.hpp b/include/glaze/chrono.hpp deleted file mode 100644 index dbecb72f25..0000000000 --- a/include/glaze/chrono.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -// Convenience header for std::chrono support -// Includes all necessary headers for chrono serialization - -#include "glaze/core/chrono.hpp" -#include "glaze/json/chrono_format.hpp" -#include "glaze/json/read.hpp" -#include "glaze/json/write.hpp" diff --git a/include/glaze/core/context.hpp b/include/glaze/core/context.hpp deleted file mode 100644 index 10836efda8..0000000000 --- a/include/glaze/core/context.hpp +++ /dev/null @@ -1,284 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include -#include -#include -#include - -#include "glaze/util/inline.hpp" - -namespace glz -{ - inline constexpr size_t max_recursive_depth_limit = 256; - - enum struct error_code : uint32_t { - // REPE compliant error codes - none, // - version_mismatch, - invalid_header, - invalid_query, - invalid_body, - parse_error, - method_not_found, - timeout, - send_error, - connection_failure, - // Other errors - // Internal to a non-null-terminated read: "the buffer ran out here", which is a completed - // read or a truncated one depending on the nesting depth. settle_end_reached decides which - // and replaces it with none or unexpected_end, so every entry point that finalizes its - // context -- glz::read, read_streaming, repe::read_params -- has stopped returning it. - // - // Two paths still hand it back. json_stream_reader raises it deliberately, to signal end of - // stream. read_jmespath and get_view_json return ctx.error without finalizing at all; they - // navigate by matching braces rather than by entering depth, so ctx.depth stays zero - // throughout and settle_end_reached cannot be dropped in as-is -- it would settle their - // truncated reads to none, which is worse than leaking. Those need their own truncation - // accounting before they can join. - end_reached, - partial_read_complete, // A non-error code for short circuiting partial reads - no_read_input, // - data_must_be_null_terminated, // - parse_number_failure, // - expected_brace, // - expected_bracket, // - expected_quote, // - expected_comma, // - expected_colon, // - exceeded_static_array_size, // - exceeded_max_recursive_depth, // - unexpected_end, // - expected_end_comment, // - syntax_error, // - unexpected_enum, // - attempt_const_read, // - attempt_member_func_read, // - attempt_read_hidden, // - invalid_nullable_read, // - invalid_variant_object, // - invalid_variant_array, // - invalid_variant_string, // - no_matching_variant_type, // - expected_true_or_false, // - constraint_violated, // - // Key errors - key_not_found, // - unknown_key, // - missing_key, // - // Other errors - invalid_flag_input, // - invalid_escape, // - u_requires_hex_digits, // - unicode_escape_conversion_failure, // - dump_int_error, // - // File errors - file_open_failure, // - file_close_failure, // - file_include_error, // - file_extension_not_supported, // - could_not_determine_extension, // - // JSON pointer access errors - nonexistent_json_ptr, // - get_wrong_type, // - seek_failure, // - // Other errors - cannot_be_referenced, // - invalid_get, // - invalid_get_fn, // - invalid_call, // - invalid_partial_key, // - name_mismatch, // - array_element_not_found, // - elements_not_convertible_to_design, // - unknown_distribution, // - invalid_distribution_elements, // - hostname_failure, // - includer_error, // - // Feature support - feature_not_supported, // - // JSON Pointer errors (RFC 6901) - invalid_json_pointer, // Malformed JSON pointer syntax (e.g., "~" at end, "~2") - // JSON Patch errors (RFC 6902) - patch_test_failed, // Test operation value mismatch (unique to RFC 6902 test op) - // Buffer errors - buffer_overflow, // Write would exceed fixed buffer capacity - invalid_length, // Length exceeds allowed limit (buffer size or user-configured max) - // Encoding errors - invalid_utf8, // Malformed UTF-8 in a string; always checked on read - // Streaming errors - streaming_unsupported // Document outruns the buffer window and this format's reader cannot refill - }; - - // Unified error context for all read/write operations - // Provides error information and byte count processed - struct error_ctx final - { - size_t count{}; // Bytes processed (read or written) - error_code ec{}; // Error code (none on success) - std::string_view custom_error_message{}; // Human-readable error context - - // Returns true when there IS an error (matches std::error_code semantics) - operator bool() const noexcept { return ec != error_code::none; } - - bool operator==(const error_code e) const noexcept { return ec == e; } - }; - - // Runtime context for configuration - // We do not template the context on iterators so that it can be easily shared across buffer implementations - // Not final: streaming_context inherits from this to add streaming-specific state - struct context - { - error_code error{}; - std::string_view custom_error_message; - // INTERNAL USE: - size_t speculation_budget{}; // Bytes of speculative (variant alternative) re-parsing left; - // seeded per read from the input size, 0 means unlimited. See charge_speculation below. - uint32_t depth{}; // Nesting depth of structures (objects/arrays) - // Used for indentation when writing and for stack overflow protection when reading - std::string current_file; // top level file path - // NOTE: The default constructor is valid for std::string_view, so we use this rather than {} - // because debuggers like jumping to std::string_view initialization calls - std::string scratch{}; // Reusable scratch buffer for intermediate parsing (key lookup, etc.) - }; - - // Concept for any context type (base or streaming) - template - concept is_context = requires(T& ctx) { - { ctx.error } -> std::same_as; - { ctx.depth } -> std::same_as; - }; - - // RAII guard for recursive descent: bumps ctx.depth on entry and restores it on exit, - // erroring out before the nesting reaches max_recursive_depth_limit so adversarial deeply - // nested input can't overflow the stack. Mirrors the per-reader guards already used by the - // BSON and JSONB binary readers; placed here so the text-format readers can share one copy. - // - // The JSON/NDJSON readers cannot use this: with a non-null-terminated buffer they overload - // ctx.depth as a completion counter (a value that closed cleanly ends at depth 0, which is how - // finalize_read_context tells "the buffer ended exactly here" from "the buffer was truncated"), - // so they count by hand and enforce the same limit inline. - template - struct depth_guard - { - Ctx& ctx; - bool entered = false; - - depth_guard(Ctx& c) noexcept : ctx(c) - { - if (ctx.depth >= max_recursive_depth_limit) [[unlikely]] { - ctx.error = error_code::exceeded_max_recursive_depth; - return; - } - ++ctx.depth; - entered = true; - } - ~depth_guard() - { - if (entered) --ctx.depth; - } - explicit operator bool() const noexcept { return entered; } - }; - - // A variant read is speculative: an alternative is parsed to find out whether it fits, and a - // rejected one is rewound and the next tried. Nest that -- a variant whose alternatives contain - // variants -- and the re-parses multiply, so a failure at the bottom of an ambiguous nest costs - // branching^depth. Measured at ~4.3x per level, which turns 189 bytes into 55 seconds. - // - // The bound is on total work rather than on nesting or attempts, because the honest measure is - // how many bytes get parsed more than once. A wide document (many variants side by side, each - // rejecting an alternative first) re-parses each element once and stays near 1x its own size, - // while the exponential case blows through any multiple of the input immediately. Reads that - // exhaust the budget stop speculating and report the failure they already have -- which is the - // outcome of a cascade anyway, since it only runs when nothing fits. - inline constexpr size_t max_speculative_parse_factor = 8; - - // ...plus a floor, because the factor alone is the wrong shape for small inputs. Resolving a - // genuinely ambiguous NESTED variant -- alternatives that differ only in a late member, so the - // rejected one parses most of the subtree before failing -- costs exponentially more per level - // even when the document is valid and the read ultimately succeeds. Glaze has always been like - // this; the bound only decides where it stops. Without a floor, a 265 byte document that read - // correctly in 9 ms would now fail, which is not an improvement. A megabyte of speculative bytes - // covers that shape to 18 levels, and gives up at 20, which is where the unbounded behavior was - // already taking a quarter of a second and doubling every two levels. The adversarial case costs - // a constant ~8 ms at any depth instead of 55 seconds at depth 12 and forever beyond that. - inline constexpr size_t min_speculative_parse_bytes = 1 << 20; - - // Charge `consumed` bytes of speculative parsing. Returns false once the budget is spent, at which - // point the caller must stop trying alternatives. A zero budget means unlimited: a context that - // never went through glz::read (a nested or hand-rolled parse) is not policed. - [[nodiscard]] GLZ_ALWAYS_INLINE bool charge_speculation(is_context auto& ctx, const size_t consumed) noexcept - { - if constexpr (requires { ctx.speculation_budget; }) { - if (ctx.speculation_budget == 0) { - return true; - } - ctx.speculation_budget = consumed >= ctx.speculation_budget ? 1 : ctx.speculation_budget - consumed; - return ctx.speculation_budget > 1; - } - else { - return true; - } - } - - // True once this read has spent its speculation budget. A stopped resolution must not then be - // reinterpreted as success by the non-null-terminated readers' "the iterator advanced, so - // something parsed" heuristic: what advanced it was an attempt that was abandoned, not accepted. - [[nodiscard]] GLZ_ALWAYS_INLINE bool speculation_exhausted(is_context auto& ctx) noexcept - { - if constexpr (requires { ctx.speculation_budget; }) { - return ctx.speculation_budget == 1; // the latched floor; 0 means unbudgeted - } - else { - return false; - } - } - - // Manual counterpart of depth_guard for the JSON/NDJSON readers described above: counts one - // nesting level and returns true when the limit is reached, in which case the caller must return - // immediately. The level is given back with a plain `--ctx.depth` at each syntactic close, so a - // bail-out leaves it counted, which is what keeps a truncated buffer from finalizing as success. - // Readers that rewind and retry (variant alternatives) must restore ctx.depth with the iterator. - [[nodiscard]] GLZ_ALWAYS_INLINE bool enter_depth(is_context auto& ctx) noexcept - { - if (ctx.depth >= max_recursive_depth_limit) [[unlikely]] { - ctx.error = error_code::exceeded_max_recursive_depth; - return true; - } - ++ctx.depth; - return false; - } - - // Runtime constraint concepts - // These detect if a user-defined context has runtime constraint fields. - // Users can inherit from glz::context and add these fields for runtime limits: - // struct my_context : glz::context { - // size_t max_string_length = 1024; - // size_t max_array_size = 100; - // size_t max_map_size = 50; - // bool allocate_raw_pointers = false; - // }; - // Use with if constexpr to ensure zero binary overhead when not used. - - template - concept has_runtime_max_string_length = requires(Ctx& ctx) { - { ctx.max_string_length } -> std::convertible_to; - }; - - template - concept has_runtime_max_array_size = requires(Ctx& ctx) { - { ctx.max_array_size } -> std::convertible_to; - }; - - template - concept has_runtime_max_map_size = requires(Ctx& ctx) { - { ctx.max_map_size } -> std::convertible_to; - }; - - template - concept has_runtime_allocate_raw_pointers = requires(Ctx& ctx) { - { ctx.allocate_raw_pointers } -> std::convertible_to; - }; -} diff --git a/include/glaze/core/error_category.hpp b/include/glaze/core/error_category.hpp deleted file mode 100644 index b49d42bb8d..0000000000 --- a/include/glaze/core/error_category.hpp +++ /dev/null @@ -1,166 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/core/context.hpp" -#include "glaze/core/meta.hpp" - -template <> -struct glz::meta -{ - static constexpr sv name = "glz::error_code"; - using enum glz::error_code; - static constexpr std::array keys{"none", - "version_mismatch", - "invalid_header", - "invalid_query", - "invalid_body", - "parse_error", - "method_not_found", - "timeout", - "send_error", - "connection_failure", - "end_reached", - "partial_read_complete", - "no_read_input", - "data_must_be_null_terminated", - "parse_number_failure", - "expected_brace", - "expected_bracket", - "expected_quote", - "expected_comma", - "expected_colon", - "exceeded_static_array_size", - "exceeded_max_recursive_depth", - "unexpected_end", - "expected_end_comment", - "syntax_error", - "unexpected_enum", - "attempt_const_read", - "attempt_member_func_read", - "attempt_read_hidden", - "invalid_nullable_read", - "invalid_variant_object", - "invalid_variant_array", - "invalid_variant_string", - "no_matching_variant_type", - "expected_true_or_false", - "constraint_violated", - "key_not_found", - "unknown_key", - "missing_key", - "invalid_flag_input", - "invalid_escape", - "u_requires_hex_digits", - "unicode_escape_conversion_failure", - "dump_int_error", - "file_open_failure", - "file_close_failure", - "file_include_error", - "file_extension_not_supported", - "could_not_determine_extension", - "nonexistent_json_ptr", - "get_wrong_type", - "seek_failure", - "cannot_be_referenced", - "invalid_get", - "invalid_get_fn", - "invalid_call", - "invalid_partial_key", - "name_mismatch", - "array_element_not_found", - "elements_not_convertible_to_design", - "unknown_distribution", - "invalid_distribution_elements", - "hostname_failure", - "includer_error", - "feature_not_supported", - "invalid_json_pointer", - "patch_test_failed", - "buffer_overflow", - "invalid_length", - "invalid_utf8", - "streaming_unsupported"}; - static constexpr std::array value{none, // - version_mismatch, // - invalid_header, // - invalid_query, // - invalid_body, // - parse_error, // - method_not_found, // - timeout, // - send_error, // - connection_failure, // - end_reached, // A non-error code for non-null terminated input buffers - partial_read_complete, - no_read_input, // - data_must_be_null_terminated, // - parse_number_failure, // - expected_brace, // - expected_bracket, // - expected_quote, // - expected_comma, // - expected_colon, // - exceeded_static_array_size, // - exceeded_max_recursive_depth, // - unexpected_end, // - expected_end_comment, // - syntax_error, // - unexpected_enum, // - attempt_const_read, // - attempt_member_func_read, // - attempt_read_hidden, // - invalid_nullable_read, // - invalid_variant_object, // - invalid_variant_array, // - invalid_variant_string, // - no_matching_variant_type, // - expected_true_or_false, // - constraint_violated, // - // Key errors - key_not_found, // - unknown_key, // - missing_key, // - // Other errors - invalid_flag_input, // - invalid_escape, // - u_requires_hex_digits, // - unicode_escape_conversion_failure, // - dump_int_error, // - // File errors - file_open_failure, // - file_close_failure, // - file_include_error, // - file_extension_not_supported, // - could_not_determine_extension, // - // JSON pointer access errors - nonexistent_json_ptr, // - get_wrong_type, // - seek_failure, // - // Other errors - cannot_be_referenced, // - invalid_get, // - invalid_get_fn, // - invalid_call, // - invalid_partial_key, // - name_mismatch, // - array_element_not_found, // - elements_not_convertible_to_design, // - unknown_distribution, // - invalid_distribution_elements, // - hostname_failure, // - includer_error, // - feature_not_supported, // - // JSON Pointer errors (RFC 6901) - invalid_json_pointer, // - // JSON Patch errors (RFC 6902) - patch_test_failed, // - // Buffer errors - buffer_overflow, // - invalid_length, // - // Encoding errors - invalid_utf8, // - // Streaming errors - streaming_unsupported}; -}; diff --git a/include/glaze/core/wrapper_traits.hpp b/include/glaze/core/wrapper_traits.hpp deleted file mode 100644 index d11b5759ed..0000000000 --- a/include/glaze/core/wrapper_traits.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -// Glaze Library -// For the license information refer to glaze.hpp - -#include "glaze/core/constraint.hpp" -#include "glaze/core/wrappers.hpp" diff --git a/include/glaze/core/wrappers.hpp b/include/glaze/core/wrappers.hpp deleted file mode 100644 index 7f28a489a5..0000000000 --- a/include/glaze/core/wrappers.hpp +++ /dev/null @@ -1,143 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/core/opts.hpp" - -namespace glz -{ - // treat a value as quoted to avoid double parsing into a value - template - struct quoted_t - { - static constexpr bool glaze_wrapper = true; - using value_type = T; - T& val; - }; - - template - struct escape_bytes_t - { - static constexpr bool glaze_wrapper = true; - using value_type = T; - T& val; - }; - - template - escape_bytes_t(T&) -> escape_bytes_t; - - template - struct opts_wrapper_t - { - static constexpr bool glaze_wrapper = true; - static constexpr auto glaze_reflect = false; - static constexpr auto opts_member = OptsMemPtr; - using value_type = T; - T& val; - }; - - template - concept is_opts_wrapper = requires { - requires T::glaze_wrapper == true; - requires T::glaze_reflect == false; - T::opts_member; - typename T::value_type; - requires std::is_lvalue_reference_v; - }; - - template - inline constexpr decltype(auto) opts_wrapper() noexcept - { - return [](auto&& val) { - using V = std::remove_reference_t; - return opts_wrapper_t{val.*MemPtr}; - }; - } - - // custom_t (user-customization wrapper for serialization members/functions) - // is defined in glaze/forward.hpp — it's pulled in transitively via opts.hpp. - - template - constexpr auto custom_impl() noexcept - { - return [](auto&& v) { return custom_t{v, From, To}; }; - } - - // When reading into an array that is appendable, the new data will be appended rather than overwrite - template - constexpr auto append_arrays = opts_wrapper(); - - // Read and write booleans as numbers - template - constexpr auto bools_as_numbers = opts_wrapper(); - - // Read and write numbers as strings - template - constexpr auto quoted_num = opts_wrapper(); - - // Treat types like std::string as numbers: read and write them without quotes - template - constexpr auto string_as_number = opts_wrapper(); - - // Deprecated: use string_as_number instead - template - [[deprecated("Use glz::string_as_number instead of glz::number")]] - constexpr auto number = opts_wrapper(); - - // Write out string like types without quotes - template - constexpr auto unquoted = opts_wrapper(); - - // Deprecated: use unquoted instead - template - [[deprecated("Use glz::unquoted instead of glz::raw")]] - constexpr auto raw = opts_wrapper(); - - // Reads into only existing fields and elements and then exits without parsing the rest of the input - template - constexpr auto partial_read = opts_wrapper(); - - // Customize reading and writing - template - constexpr auto custom = custom_impl(); - - template - inline constexpr decltype(auto) escape_bytes_impl() noexcept - { - return [](auto&& val) { return escape_bytes_t>{val.*MemPtr}; }; - } - - // Treat char arrays as byte sequences to be fully escaped - template - constexpr auto escape_bytes = escape_bytes_impl(); - - // Limit string length or array size when reading - // For strings: limits max_string_length - // For arrays/vectors: limits max_array_size - template - struct max_length_t - { - static constexpr bool glaze_wrapper = true; - static constexpr auto glaze_reflect = false; - static constexpr size_t max_len = MaxLen; - using value_type = T; - T& val; - }; - - template - inline constexpr decltype(auto) max_length_impl() noexcept - { - return [](auto&& val) { - using V = std::remove_reference_t; - return max_length_t{val.*MemPtr}; - }; - } - - // Limit string length or array size when reading from binary formats - // Usage: glz::max_length<&T::field, 100> - template - constexpr auto max_length = max_length_impl(); -} diff --git a/include/glaze/csv.hpp b/include/glaze/csv.hpp deleted file mode 100644 index bd92a5d402..0000000000 --- a/include/glaze/csv.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/core/as_array_wrapper.hpp" -#include "glaze/core/wrapper_traits.hpp" -#include "glaze/csv/read.hpp" -#include "glaze/csv/skip.hpp" -#include "glaze/csv/write.hpp" -#include "glaze/thread/atomic.hpp" diff --git a/include/glaze/exceptions/json_schema_exceptions.hpp b/include/glaze/exceptions/json_schema_exceptions.hpp deleted file mode 100644 index 188cdbdb5a..0000000000 --- a/include/glaze/exceptions/json_schema_exceptions.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#if __cpp_exceptions - -#include "glaze/exceptions/core_exceptions.hpp" -#include "glaze/json/schema.hpp" - -namespace glz::ex -{ - template - void write_json_schema(Buffer&& buffer) - { - const auto ec = glz::write_json_schema(buffer); - if (bool(ec)) [[unlikely]] { - throw std::runtime_error(format_error(ec, buffer)); - } - } - - template - [[nodiscard]] std::string write_json_schema() - { - std::string buffer{}; - glz::ex::write_json_schema(buffer); - return buffer; - } -} - -#endif diff --git a/include/glaze/format/format_to.hpp b/include/glaze/format/format_to.hpp deleted file mode 100644 index cc3e7ab871..0000000000 --- a/include/glaze/format/format_to.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/core/write.hpp" -#include "glaze/util/itoa.hpp" -#include "glaze/util/zmij.hpp" - -namespace glz -{ - template - void format_to(std::string& buffer, T&& value) - { - auto ix = buffer.size(); - buffer.resize((std::max)(buffer.size() * 2, ix + 64)); - - const auto start = buffer.data() + ix; - const auto end = glz::to_chars(start, std::forward(value)); - ix += size_t(end - start); - buffer.resize(ix); - } -} diff --git a/include/glaze/glaze_exceptions.hpp b/include/glaze/glaze_exceptions.hpp deleted file mode 100644 index 0c100c2216..0000000000 --- a/include/glaze/glaze_exceptions.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#if __cpp_exceptions - -// These files provide convenience functions that throw C++ exceptions, which can make code cleaner for users - -#include "glaze/exceptions/binary_exceptions.hpp" -#include "glaze/exceptions/cbor_exceptions.hpp" -#include "glaze/exceptions/csv_exceptions.hpp" -#include "glaze/exceptions/json_exceptions.hpp" -#include "glaze/exceptions/msgpack_exceptions.hpp" - -namespace glz::ex -{ - template - void read(auto& value, auto&& buffer) - { - auto ec = glz::read(value, buffer); - if (ec) { - if constexpr (Opts.format == JSON) { - throw std::runtime_error("read error: " + glz::format_error(ec, buffer)); - } - else { - throw std::runtime_error("read error"); - } - } - } - - template - void write(T&& value, Buffer& buffer) noexcept - { - glz::write(std::forward(value), buffer); - } - - template - size_t write(T&& value, Buffer&& buffer) noexcept - { - return glz::write(std::forward(value), std::forward(buffer)); - } -} - -#endif diff --git a/include/glaze/json.hpp b/include/glaze/json.hpp deleted file mode 100644 index a0a6d7004e..0000000000 --- a/include/glaze/json.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/core/as_array_wrapper.hpp" -#include "glaze/core/istream_buffer.hpp" -#include "glaze/core/manage.hpp" -#include "glaze/core/wrapper_traits.hpp" -#include "glaze/json/escape_unicode.hpp" -#include "glaze/json/float_format.hpp" -#include "glaze/json/generic.hpp" -#include "glaze/json/invoke.hpp" -#include "glaze/json/json_concepts.hpp" -#include "glaze/json/json_ptr.hpp" -#include "glaze/json/json_stream.hpp" -#include "glaze/json/lazy.hpp" -#include "glaze/json/max_write_precision.hpp" -#include "glaze/json/minify.hpp" -#include "glaze/json/ndjson.hpp" -#include "glaze/json/prettify.hpp" -#include "glaze/json/ptr.hpp" -#include "glaze/json/raw_string.hpp" -#include "glaze/json/read.hpp" -#include "glaze/json/schema.hpp" -#include "glaze/json/wrappers.hpp" -#include "glaze/json/write.hpp" -#include "glaze/thread/atomic.hpp" diff --git a/include/glaze/jsonb.hpp b/include/glaze/jsonb.hpp deleted file mode 100644 index 05bb443f20..0000000000 --- a/include/glaze/jsonb.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/jsonb/header.hpp" -#include "glaze/jsonb/jsonb_to_json.hpp" -#include "glaze/jsonb/read.hpp" -#include "glaze/jsonb/skip.hpp" -#include "glaze/jsonb/text_decode.hpp" -#include "glaze/jsonb/write.hpp" diff --git a/include/glaze/msgpack.hpp b/include/glaze/msgpack.hpp deleted file mode 100644 index 354ba920ce..0000000000 --- a/include/glaze/msgpack.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/msgpack/read.hpp" -#include "glaze/msgpack/write.hpp" diff --git a/include/glaze/reflection/requires_key.hpp b/include/glaze/reflection/requires_key.hpp deleted file mode 100644 index 87cbc8b174..0000000000 --- a/include/glaze/reflection/requires_key.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -namespace glz -{ - template - struct meta; - - /// Concept for when requires_key is available in glz::meta - template - concept meta_has_requires_key = requires(T t, const std::string_view s, const bool is_nullable) { - { glz::meta>::requires_key(s, is_nullable) } -> std::same_as; - }; -} \ No newline at end of file diff --git a/include/glaze/toml.hpp b/include/glaze/toml.hpp deleted file mode 100644 index b2d69ca7be..0000000000 --- a/include/glaze/toml.hpp +++ /dev/null @@ -1,9 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/core/as_array_wrapper.hpp" -#include "glaze/core/wrapper_traits.hpp" -#include "glaze/toml/read.hpp" -#include "glaze/toml/write.hpp" diff --git a/include/glaze/util/convert.hpp b/include/glaze/util/convert.hpp deleted file mode 100644 index bc4dbff346..0000000000 --- a/include/glaze/util/convert.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include -#include - -namespace glz -{ - // Creates a uint16_t from two chars that matches memcpy behavior on any endianness - consteval uint16_t to_uint16_t(const char chars[2]) - { - if constexpr (std::endian::native == std::endian::little) { - return uint16_t(chars[0]) | (uint16_t(chars[1]) << 8); - } - else { - return (uint16_t(chars[0]) << 8) | uint16_t(chars[1]); - } - } -} diff --git a/include/glaze/util/expected.hpp b/include/glaze/util/expected.hpp deleted file mode 100644 index 294b3cf886..0000000000 --- a/include/glaze/util/expected.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include -#include -#include -#include - -namespace glz -{ - template - using expected = std::expected; - - template - concept is_expected = - std::same_as, expected >; - -#ifdef __clang__ - template - struct unexpected : public std::unexpected - { - using std::unexpected::unexpected; - }; - template - unexpected(Unexpected) -> unexpected; -#else - template - using unexpected = std::unexpected; -#endif -} \ No newline at end of file diff --git a/include/glaze/util/tuple.hpp b/include/glaze/util/tuple.hpp deleted file mode 100644 index 05900ec944..0000000000 --- a/include/glaze/util/tuple.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include - -#include "glaze/reflection/get_name.hpp" -#include "glaze/tuplet/tuple.hpp" -#include "glaze/util/for_each.hpp" -#include "glaze/util/string_literal.hpp" - -namespace glz -{ - template - concept is_std_tuple = is_specialization_v; -} diff --git a/include/glaze/api/api.hpp b/modules/glaze/api/api.ixx similarity index 69% rename from include/glaze/api/api.hpp rename to modules/glaze/api/api.ixx index 1e6690f67f..cd590317c9 100644 --- a/include/glaze/api/api.hpp +++ b/modules/glaze/api/api.ixx @@ -1,19 +1,33 @@ // Glaze Library -// For the license information refer to glaze.hpp +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/api.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.api; -#pragma once +import glaze.api.trait; -#include -#include -#include -#include -#include +import std; -#include "glaze/api/std/string.hpp" -#include "glaze/api/trait.hpp" -#include "glaze/core/context.hpp" -#include "glaze/core/opts.hpp" -#include "glaze/util/expected.hpp" +import glaze.api.std.string; + +import glaze.core.context; +import glaze.core.opts; + +import glaze.util.expected; +import glaze.util.for_each; +import glaze.util.string_literal; + +using std::uint32_t; namespace glz { @@ -23,7 +37,7 @@ namespace glz using func_return_t = std::conditional_t, std::reference_wrapper>, R>; - struct api + export struct api { api() noexcept = default; api(const api&) noexcept = default; @@ -62,14 +76,14 @@ namespace glz std::string error{}; }; - using iface = std::map()>, std::less<>>; + export using iface = std::map()>, std::less<>>; template T* api::get(const sv path) noexcept { - static constexpr auto hash = glz::hash(); - auto p = get(path); - if (p.first && p.second == hash) { + static constexpr auto type_hash = glz::hash(); + auto p = this->get(path); + if (p.first && p.second == type_hash) { return static_cast(p.first); } return nullptr; @@ -78,8 +92,8 @@ namespace glz template glz::expected api::get_fn(const sv path) noexcept { - static constexpr auto hash = glz::hash(); - auto d = get_fn(path, hash); + static constexpr auto type_hash = glz::hash(); + auto d = this->get_fn(path, type_hash); if (d) { T copy = *static_cast(d.get()); return copy; @@ -93,10 +107,10 @@ namespace glz glz::expected, error_code> api::call(const sv path, Args&&... args) noexcept { using F = std::function; - static constexpr auto hash = glz::hash(); + static constexpr auto type_hash = glz::hash(); static constexpr auto N = sizeof...(Args); - std::array arguments; + std::array arguments{}; auto tuple_args = std::forward_as_tuple(std::forward(args)...); @@ -104,7 +118,7 @@ namespace glz if constexpr (std::is_pointer_v) { void* ptr{}; - const auto success = caller(path, hash, ptr, arguments); + const auto success = this->caller(path, type_hash, ptr, arguments); if (success) { return static_cast(ptr); @@ -112,7 +126,7 @@ namespace glz } else if constexpr (std::is_void_v) { void* ptr = nullptr; - const auto success = caller(path, hash, ptr, arguments); + const auto success = this->caller(path, type_hash, ptr, arguments); if (success) { return expected{}; @@ -120,7 +134,7 @@ namespace glz } else if constexpr (std::is_lvalue_reference_v) { void* ptr{}; - const auto success = caller(path, hash, ptr, arguments); + const auto success = this->caller(path, type_hash, ptr, arguments); if (success) { return std::ref(*static_cast*>(ptr)); @@ -129,7 +143,7 @@ namespace glz else { Ret value{}; void* ptr = &value; - const auto success = caller(path, hash, ptr, arguments); + const auto success = this->caller(path, type_hash, ptr, arguments); if (success) { return value; @@ -139,7 +153,7 @@ namespace glz return glz::unexpected(error_code::invalid_call); } - using iface_fn = std::shared_ptr (*)(); + export using iface_fn = std::shared_ptr (*)(); } } @@ -149,4 +163,4 @@ namespace glz #define DLL_EXPORT #endif -extern "C" DLL_EXPORT glz::iface_fn glz_iface() noexcept; +export extern "C" DLL_EXPORT glz::iface_fn glz_iface() noexcept; diff --git a/include/glaze/api/hash.hpp b/modules/glaze/api/hash.ixx similarity index 88% rename from include/glaze/api/hash.hpp rename to modules/glaze/api/hash.ixx index 380a637609..b500bd5475 100644 --- a/include/glaze/api/hash.hpp +++ b/modules/glaze/api/hash.ixx @@ -1,12 +1,22 @@ // Glaze Library -// For the license information refer to glaze.hpp +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/hash.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.hash; -#pragma once +import std; -#include +import glaze.api.xxh64; -#include "glaze/api/xxh64.hpp" -#include "glaze/core/meta.hpp" +import glaze.core.meta; + +import glaze.util.string_literal; // Collision calculations done with the formula: e^((-k * (k - 1)/(2 * N))) // The approximation error tends to zero as N increases, and we are dealing with a large N @@ -20,13 +30,16 @@ // bit: 1220 times 128 bit: 2.2494655e22 times (or 22 sextillion times) 256 bit: 7.6545351e60 times From these // calculations it is apparent that a 128 bit hash is more than sufficient -namespace glz +using std::uint64_t; +using std::size_t; + +export namespace glz { template consteval auto make_array() { return [](std::index_sequence) { - return std::array{static_cast(((Value >> (CHAR_BIT * I)) & 0xff))...}; + return std::array{static_cast(((Value >> (std::numeric_limits::digits * I)) & 0xff))...}; }(std::make_index_sequence{}); } diff --git a/include/glaze/api/impl.hpp b/modules/glaze/api/impl.ixx similarity index 88% rename from include/glaze/api/impl.hpp rename to modules/glaze/api/impl.ixx index 9d70997108..9a7a334d2f 100644 --- a/include/glaze/api/impl.hpp +++ b/modules/glaze/api/impl.ixx @@ -1,28 +1,62 @@ // Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include "glaze/api/api.hpp" -#include "glaze/api/std/array.hpp" -#include "glaze/api/std/deque.hpp" -#include "glaze/api/std/functional.hpp" -#include "glaze/api/std/list.hpp" -#include "glaze/api/std/map.hpp" -#include "glaze/api/std/optional.hpp" -#include "glaze/api/std/shared_ptr.hpp" -#include "glaze/api/std/string.hpp" -#include "glaze/api/std/tuple.hpp" -#include "glaze/api/std/unique_ptr.hpp" -#include "glaze/api/std/variant.hpp" -#include "glaze/api/std/vector.hpp" -#include "glaze/api/tuplet.hpp" -#include "glaze/api/type_support.hpp" -#include "glaze/beve/read.hpp" -#include "glaze/beve/write.hpp" -#include "glaze/glaze.hpp" -#include "glaze/json/read.hpp" -#include "glaze/json/write.hpp" +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/impl.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.impl; + +import std; + +export import glaze.api.api; +import glaze.api.tuplet; +import glaze.api.type_support; +import glaze.api.trait; + +import glaze.api.std.array; +import glaze.api.std.deque; +import glaze.api.std.functional; +import glaze.api.std.list; +import glaze.api.std.map; +import glaze.api.std.optional; +import glaze.api.std.shared_ptr; +import glaze.api.std.string; +import glaze.api.std.tuple; +import glaze.api.std.unique_ptr; +import glaze.api.std.unordered_map; +import glaze.api.std.variant; +import glaze.api.std.vector; + +import glaze.beve.read; +import glaze.beve.write; + +import glaze.json.read; +import glaze.json.write; + +import glaze.core.read; +import glaze.core.seek; +import glaze.core.common; +import glaze.core.context; +import glaze.core.opts; +import glaze.core.meta; + +import glaze.util.for_each; +import glaze.util.type_traits; +import glaze.util.tuple; + +import glaze.tuplet; + +export import glaze; + +import glaze.util.string_literal; + +using std::uint32_t; +using std::size_t; namespace glz { @@ -45,8 +79,8 @@ namespace glz if (format == JSON) { success = seek([&](auto&& val) { pe = glz::read(val, data); }, user, path); - } - else { + } + else { success = seek([&](auto&& val) { pe = glz::read(val, data); }, user, path); } @@ -292,7 +326,7 @@ namespace glz return std::shared_ptr>{new impl{}, [](impl* ptr) { delete ptr; }}; } - template + export template iface_fn make_iface() { return [] { diff --git a/include/glaze/api/lib.hpp b/modules/glaze/api/lib.ixx similarity index 63% rename from include/glaze/api/lib.hpp rename to modules/glaze/api/lib.ixx index b9989fb613..49dbd6f78f 100644 --- a/include/glaze/api/lib.hpp +++ b/modules/glaze/api/lib.ixx @@ -1,62 +1,64 @@ // Glaze Library -// For the license information refer to glaze.hpp - -#pragma once - -#include -#include -#include - -#include "glaze/api/api.hpp" +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/lib.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +// glz:header std= +module; #if defined(_WIN32) || defined(__CYGWIN__) #ifndef GLAZE_API_ON_WINDOWS #define GLAZE_API_ON_WINDOWS #endif -#endif - -#ifdef GLAZE_API_ON_WINDOWS -#ifdef NOMINMAX -#include -#else +#ifndef NOMINMAX #define NOMINMAX +#define GLAZE_API_UNDEF_NOMINMAX +#endif #include +#ifdef GLAZE_API_UNDEF_NOMINMAX #undef NOMINMAX +#undef GLAZE_API_UNDEF_NOMINMAX #endif -#define SHARED_LIBRARY_EXTENSION ".dll" -#define SHARED_LIBRARY_PREFIX "" -#elif __APPLE__ +#elif defined(__APPLE__) #include -#define SHARED_LIBRARY_EXTENSION ".dylib" -#define SHARED_LIBRARY_PREFIX "lib" #elif __has_include() #include -#define SHARED_LIBRARY_EXTENSION ".so" -#define SHARED_LIBRARY_PREFIX "lib" #endif +export module glaze.api.lib; + +import std; + +import glaze.api.api; namespace glz { #ifdef GLAZE_API_ON_WINDOWS + inline constexpr auto shared_library_extension = ".dll"; using lib_t = HINSTANCE; +#elif defined(__APPLE__) + inline constexpr auto shared_library_extension = ".dylib"; + using lib_t = void*; #else + inline constexpr auto shared_library_extension = ".so"; using lib_t = void*; #endif - struct lib_loader final + export struct lib_loader final { - using create = glz::iface_fn (*)(void) noexcept; + using create = iface_fn (*)() noexcept; iface api_map{}; std::vector loaded_libs{}; - void load(const sv path) + void load(const std::string_view path) { const std::filesystem::path libpath(path); if (std::filesystem::is_directory(libpath)) { load_libs(path); } - else if (libpath.extension() == SHARED_LIBRARY_EXTENSION) { + else if (libpath.extension() == shared_library_extension) { load_lib(libpath.string()); } else { @@ -64,17 +66,17 @@ namespace glz } } - void load_libs(const sv directory) + void load_libs(const std::string_view directory) { - std::filesystem::directory_entry dir(directory); + const std::filesystem::path dir{directory}; for (const auto& entry : std::filesystem::directory_iterator(dir)) { - if (entry.is_regular_file() && entry.path().extension() == SHARED_LIBRARY_EXTENSION) { + if (entry.is_regular_file() && entry.path().extension() == shared_library_extension) { load_lib(entry.path().string()); } } } - auto& operator[](const sv lib_name) { return api_map[std::string(lib_name)]; } + auto& operator[](const std::string_view lib_name) { return api_map[std::string(lib_name)]; } lib_loader() = default; lib_loader(const lib_loader&) = delete; @@ -101,7 +103,7 @@ namespace glz { #ifdef GLAZE_API_ON_WINDOWS std::filesystem::path file_path(path); - lib_t loaded_lib = LoadLibraryW(file_path.native().c_str()); + lib_t loaded_lib = LoadLibraryW(file_path.c_str()); #else lib_t loaded_lib = dlopen(path.c_str(), RTLD_LAZY); #endif @@ -112,16 +114,16 @@ namespace glz #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" - auto* ptr = reinterpret_cast(GetProcAddress(loaded_lib, "glz_iface")); + const auto ptr = reinterpret_cast(GetProcAddress(loaded_lib, "glz_iface")); #pragma GCC diagnostic pop #else - auto* ptr = reinterpret_cast(GetProcAddress(loaded_lib, "glz_iface")); + const auto ptr = reinterpret_cast(GetProcAddress(loaded_lib, "glz_iface")); #endif #else auto* ptr = reinterpret_cast(dlsym(loaded_lib, "glz_iface")); #endif if (ptr) { - std::shared_ptr shared_iface_ptr = (*ptr)()(); + std::shared_ptr shared_iface_ptr = ptr()(); api_map.merge(*shared_iface_ptr); return true; } @@ -137,7 +139,7 @@ namespace glz #else static std::string suffix = "_d"; #endif - const std::filesystem::path combined_path(path + suffix + SHARED_LIBRARY_EXTENSION); + const std::filesystem::path combined_path(path + suffix + shared_library_extension); return (load_lib(std::filesystem::canonical(combined_path).string())); } diff --git a/include/glaze/api/std/array.hpp b/modules/glaze/api/std/array.ixx similarity index 69% rename from include/glaze/api/std/array.hpp rename to modules/glaze/api/std/array.ixx index 0409491062..0e63d656ea 100644 --- a/include/glaze/api/std/array.hpp +++ b/modules/glaze/api/std/array.ixx @@ -1,13 +1,19 @@ // Glaze Library -// For the license information refer to glaze.hpp +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/array.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.std.array; -#pragma once +import std; -#include +import glaze.core.meta; +import glaze.util.string_literal; -#include "glaze/core/meta.hpp" +using std::size_t; -namespace glz +export namespace glz { namespace detail { diff --git a/modules/glaze/api/std/deque.ixx b/modules/glaze/api/std/deque.ixx new file mode 100644 index 0000000000..59d72cd4f9 --- /dev/null +++ b/modules/glaze/api/std/deque.ixx @@ -0,0 +1,20 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/deque.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.deque; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +export namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = join_v, name_v, chars<">">>; + }; +} diff --git a/include/glaze/api/std/functional.hpp b/modules/glaze/api/std/functional.ixx similarity index 78% rename from include/glaze/api/std/functional.hpp rename to modules/glaze/api/std/functional.ixx index adf3046b01..85f447eed2 100644 --- a/include/glaze/api/std/functional.hpp +++ b/modules/glaze/api/std/functional.ixx @@ -1,14 +1,22 @@ // Glaze Library -// For the license information refer to glaze.hpp +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/functional.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.std.functional; -#pragma once +import std; -#include +import glaze.core.common; +import glaze.core.meta; +import glaze.tuplet; +import glaze.util.string_literal; +import glaze.util.type_traits; -#include "glaze/core/common.hpp" -#include "glaze/core/meta.hpp" +using std::size_t; -namespace glz +export namespace glz { namespace detail { @@ -36,10 +44,10 @@ namespace glz constexpr std::string_view expander_v = expander::value; } - template + template concept function = is_specialization_v; - template + template struct meta { static constexpr auto impl() noexcept diff --git a/modules/glaze/api/std/list.ixx b/modules/glaze/api/std/list.ixx new file mode 100644 index 0000000000..e76ecc7b8f --- /dev/null +++ b/modules/glaze/api/std/list.ixx @@ -0,0 +1,20 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/list.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.list; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +export namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = join_v, name_v, chars<">">>; + }; +} diff --git a/modules/glaze/api/std/map.ixx b/modules/glaze/api/std/map.ixx new file mode 100644 index 0000000000..891551c00f --- /dev/null +++ b/modules/glaze/api/std/map.ixx @@ -0,0 +1,21 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/map.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.map; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +export namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = + join_v, name_v, chars<",">, name_v, chars<">">>; + }; +} diff --git a/modules/glaze/api/std/optional.ixx b/modules/glaze/api/std/optional.ixx new file mode 100644 index 0000000000..92e5c3a24e --- /dev/null +++ b/modules/glaze/api/std/optional.ixx @@ -0,0 +1,20 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/optional.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.optional; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +export namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = join_v, name_v, chars<">">>; + }; +} diff --git a/modules/glaze/api/std/set.ixx b/modules/glaze/api/std/set.ixx new file mode 100644 index 0000000000..55e050a040 --- /dev/null +++ b/modules/glaze/api/std/set.ixx @@ -0,0 +1,20 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/set.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.set; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = join_v, name_v, chars<">">>; + }; +} diff --git a/modules/glaze/api/std/shared_ptr.ixx b/modules/glaze/api/std/shared_ptr.ixx new file mode 100644 index 0000000000..90d8a2d684 --- /dev/null +++ b/modules/glaze/api/std/shared_ptr.ixx @@ -0,0 +1,20 @@ +// Glaze Library +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/shared_ptr.hpp" +// glz:header std= +// glz:header std= +export module glaze.api.std.shared_ptr; + +import std; + +import glaze.core.meta; +import glaze.util.string_literal; + +export namespace glz +{ + template + struct meta> + { + static constexpr std::string_view name = join_v, name_v, chars<">">>; + }; +} diff --git a/include/glaze/api/std/span.hpp b/modules/glaze/api/std/span.ixx similarity index 59% rename from include/glaze/api/std/span.hpp rename to modules/glaze/api/std/span.ixx index 5fc5866262..1c208920c0 100644 --- a/include/glaze/api/std/span.hpp +++ b/modules/glaze/api/std/span.ixx @@ -1,24 +1,31 @@ // Glaze Library -// For the license information refer to glaze.hpp +// For the license information refer to glaze.ixx +// glz:header path="glaze/api/std/span.hpp" +// glz:header std= +// glz:header std= +// glz:header std= +export module glaze.api.std.span; -#pragma once +import std; -#include +import glaze.api.hash; -#include "glaze/api/hash.hpp" -#include "glaze/core/meta.hpp" +import glaze.core.meta; +import glaze.util.string_literal; -namespace glz +using std::size_t; + +export namespace glz { template class> inline constexpr bool is_span_v = false; template