From eef76c200e1d5b88a2cf0b5264756c4a020a88db Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 28 Apr 2025 21:52:26 +0200 Subject: [PATCH] Make library work with C++20 modules (#4764) * :white_check_mark: add test for C++20 modules Signed-off-by: Niels Lohmann * :rotating_light: fix warning Signed-off-by: Niels Lohmann * Add missing header (#4763) * :bug: add missing header Signed-off-by: Niels Lohmann * :rotating_light: fix warning Signed-off-by: Niels Lohmann * :rotating_light: fix warning Signed-off-by: Niels Lohmann --------- Signed-off-by: Niels Lohmann --------- Signed-off-by: Niels Lohmann --- .github/workflows/ubuntu.yml | 17 ++++++++++++++++- cmake/ci.cmake | 11 +++++++++++ include/nlohmann/detail/input/binary_reader.hpp | 2 +- include/nlohmann/detail/string_escape.hpp | 2 +- single_include/nlohmann/json.hpp | 4 ++-- tests/module_cpp20/CMakeLists.txt | 12 ++++++++++++ tests/module_cpp20/json.cpp | 17 +++++++++++++++++ tests/module_cpp20/main.cpp | 6 ++++++ 8 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 tests/module_cpp20/CMakeLists.txt create mode 100644 tests/module_cpp20/json.cpp create mode 100644 tests/module_cpp20/main.cpp diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 6defddc2b..179038fd6 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -143,7 +143,7 @@ jobs: strategy: matrix: # older GCC docker images (4, 5, 6) fail to check out code - compiler: ['7', '8', '9', '10', '11', '12', '13', '14', 'latest'] + compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', 'latest'] container: gcc:${{ matrix.compiler }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -221,6 +221,21 @@ jobs: - name: Build run: cmake --build build --target ci_cuda_example + ci_module_cpp20: + strategy: + matrix: + container: ['gcc:latest', 'silkeh/clang:latest'] + runs-on: ubuntu-latest + container: ${{ matrix.container }} + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Get latest CMake and ninja + uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1 + - name: Run CMake + run: cmake -S . -B build -DJSON_CI=On + - name: Build + run: cmake --build build --target ci_module_cpp20 + ci_icpc: runs-on: ubuntu-latest container: ghcr.io/nlohmann/json-ci:v2.2.0 diff --git a/cmake/ci.cmake b/cmake/ci.cmake index ef4c257b1..8c0d2106b 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -659,6 +659,17 @@ add_custom_target(ci_cuda_example COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example ) +############################################################################### +# C++ 20 modules +############################################################################### + +add_custom_target(ci_module_cpp20 + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -S${PROJECT_SOURCE_DIR}/tests/module_cpp20 -B${PROJECT_BINARY_DIR}/ci_module_cpp20 + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/ci_module_cpp20 +) + ############################################################################### # Intel C++ Compiler ############################################################################### diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 92b85572a..ed0ee5b7c 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -53,7 +53,7 @@ enum class cbor_tag_handler_t @note from https://stackoverflow.com/a/1001328/266378 */ -static inline bool little_endianness(int num = 1) noexcept +inline bool little_endianness(int num = 1) noexcept { return *reinterpret_cast(&num) == 1; } diff --git a/include/nlohmann/detail/string_escape.hpp b/include/nlohmann/detail/string_escape.hpp index 7f0231819..d969a9ed4 100644 --- a/include/nlohmann/detail/string_escape.hpp +++ b/include/nlohmann/detail/string_escape.hpp @@ -62,7 +62,7 @@ inline StringType escape(StringType s) * Note the order of escaping "~1" to "/" and "~0" to "~" is important. */ template -static void unescape(StringType& s) +inline void unescape(StringType& s) { replace_substring(s, StringType{"~1"}, StringType{"/"}); replace_substring(s, StringType{"~0"}, StringType{"~"}); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index dabad062d..850cd8ebf 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3126,7 +3126,7 @@ inline StringType escape(StringType s) * Note the order of escaping "~1" to "/" and "~0" to "~" is important. */ template -static void unescape(StringType& s) +inline void unescape(StringType& s) { replace_substring(s, StringType{"~1"}, StringType{"/"}); replace_substring(s, StringType{"~0"}, StringType{"~"}); @@ -9868,7 +9868,7 @@ enum class cbor_tag_handler_t @note from https://stackoverflow.com/a/1001328/266378 */ -static inline bool little_endianness(int num = 1) noexcept +inline bool little_endianness(int num = 1) noexcept { return *reinterpret_cast(&num) == 1; } diff --git a/tests/module_cpp20/CMakeLists.txt b/tests/module_cpp20/CMakeLists.txt new file mode 100644 index 000000000..23884342c --- /dev/null +++ b/tests/module_cpp20/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.28) + +project(json_test CXX) + +add_executable(json_test) + +target_sources(json_test + PRIVATE main.cpp + PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES json.cpp) + +target_compile_features(json_test PUBLIC cxx_std_20) +target_include_directories(json_test PRIVATE ../../include) diff --git a/tests/module_cpp20/json.cpp b/tests/module_cpp20/json.cpp new file mode 100644 index 000000000..8d5cc9147 --- /dev/null +++ b/tests/module_cpp20/json.cpp @@ -0,0 +1,17 @@ +module; +#include +export module json; + +export namespace nlohmann +{ +using ::nlohmann::adl_serializer; + +using ::nlohmann::basic_json; +using ::nlohmann::json_pointer; + +using ::nlohmann::json; +using ::nlohmann::ordered_json; +using ::nlohmann::ordered_map; + +using ::nlohmann::json_pointer; +} // namespace nlohmann diff --git a/tests/module_cpp20/main.cpp b/tests/module_cpp20/main.cpp new file mode 100644 index 000000000..ad7bd8b1a --- /dev/null +++ b/tests/module_cpp20/main.cpp @@ -0,0 +1,6 @@ +import json; + +int main() +{ + nlohmann::json j; +}