Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,49 @@ jobs:
./build/benchmarks/json/reflect-cpp-json-benchmarks --benchmark_filter=canada >> $GITHUB_STEP_SUMMARY
./build/benchmarks/json/reflect-cpp-json-benchmarks --benchmark_filter=licenses >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

linux-modules:
strategy:
fail-fast: false
matrix:
include:
- compiler: gcc
compiler-version: 15
- compiler: llvm
compiler-version: 19
name: "linux modules (${{ matrix.compiler }}-${{ matrix.compiler-version }})"
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Install compiler and dependencies
run: |
sudo apt update
if [[ "${{ matrix.compiler }}" == "gcc" ]]; then
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install -y g++-15 ninja-build
else
sudo apt install -y clang-19 ninja-build
fi
- name: Run vcpkg
uses: lukka/run-vcpkg@v11
- name: Compile modules
run: |
if [[ "${{ matrix.compiler }}" == "gcc" ]]; then
export CC=gcc-15
export CXX=g++-15
else
export CC=clang-19
export CXX=clang++-19
fi
$CXX --version
cmake -S . -B build -G Ninja \
-DCMAKE_CXX_STANDARD=23 \
-DREFLECTCPP_BUILD_MODULES=ON \
-DREFLECTCPP_BUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build -j4
4 changes: 2 additions & 2 deletions .github/workflows/macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ jobs:
fi
$CXX --version
if [[ "${{ matrix.format }}" == "benchmarks" ]]; then
cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_BENCHMARKS=ON -DREFLECTCPP_ALL_FORMATS=ON -DREFLECTCPP_BUILD_MODULES=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
else
cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_ALL_FORMATS=ON -DREFLECTCPP_CHECK_HEADERS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_ALL_FORMATS=ON -DREFLECTCPP_CHECK_HEADERS=ON -DREFLECTCPP_BUILD_MODULES=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
fi
cmake --build build -j 4
- name: Run tests
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,24 @@ jobs:
run: |
ctest --test-dir build -C Release --output-on-failure

windows-msvc-modules:
name: "windows-msvc modules"
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- uses: ilammy/msvc-dev-cmd@v1
- uses: lukka/run-vcpkg@v11
- name: Compile modules
shell: bash
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_CXX_STANDARD=23 \
-DREFLECTCPP_BUILD_MODULES=ON \
-DREFLECTCPP_BUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j4

13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.23)
cmake_minimum_required(VERSION 3.28)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand Down Expand Up @@ -27,6 +27,7 @@ option(REFLECTCPP_BOOST_SERIALIZATION "Enable Boost.Serialization support" ${REF
option(REFLECTCPP_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(REFLECTCPP_BUILD_TESTS "Build tests" OFF)
option(REFLECTCPP_CHECK_HEADERS "Make sure that all headers are self-contained" OFF)
option(REFLECTCPP_BUILD_MODULES "Build reflectcpp as a C++ module" OFF)

option(REFLECTCPP_USE_BUNDLED_DEPENDENCIES "Use the bundled dependencies" ON)

Expand Down Expand Up @@ -469,13 +470,16 @@ set_target_properties(reflectcpp PROPERTIES LINKER_LANGUAGE CXX)
target_sources(reflectcpp PRIVATE ${REFLECT_CPP_SOURCES})
target_precompile_headers(reflectcpp PRIVATE [["rfl.hpp"]] <iostream> <string> <functional>)

if (REFLECTCPP_BUILD_TESTS)
if (REFLECTCPP_BUILD_MODULES)
add_subdirectory(src/modules)
endif()

if (REFLECTCPP_BUILD_TESTS AND NOT REFLECTCPP_BUILD_MODULES)
add_library(reflectcpp_tests_crt INTERFACE)
target_link_libraries(reflectcpp_tests_crt INTERFACE reflectcpp GTest::gtest_main)

enable_testing()
find_package(GTest CONFIG REQUIRED)
add_subdirectory(tests)
endif ()

if (REFLECTCPP_BUILD_BENCHMARKS)
Expand Down Expand Up @@ -517,6 +521,7 @@ if(REFLECTCPP_CHECK_HEADERS)
endforeach()
endif()


if (REFLECTCPP_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,33 @@ In addition, it supports the following custom containers:

Finally, it is very easy to extend full support to your own classes, refer to the [documentation](https://rfl.getml.com/docs-readme) for details.

### Module support

reflect-cpp has support for C++20 modules. To enable, pass `REFLECTCPP_BUILD_MODULES` to CMake. You must have CMake 3.28 or higher, and any build system that supports modules (such as Ninja).

```cpp
import std;
import rfl;

using std::string;

struct Person {
string first_name;
string last_name;
int age;
};

const Person homer = Person{
.first_name = "Homer",
.last_name = "Simpson",
.age = 45
};

// We can now write into and read from a JSON string.
const string json_string = rfl::json::write(homer);
auto homer2 = rfl::json::read<Person>(json_string).value();
```


## Installation

Expand Down
2 changes: 1 addition & 1 deletion include/rfl/capnproto/schema/CapnProtoTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct CapnProtoTypes {
std::map<std::string, schema::Type> unions_;
};

const char* MAP_DEFINITION = R"(
inline const char* MAP_DEFINITION = R"(
struct Map(Value) {
entries @0 :List(Entry);
struct Entry {
Expand Down
2 changes: 1 addition & 1 deletion include/rfl/default.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct Default {};

/// Convenience constant for the Default type.
/// Can be used like: MyField field = rfl::default_value;
inline static const auto default_value = Default{};
inline const auto default_value = Default{};

} // namespace rfl

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#ifndef RFL_PARSING_CALL_DESTRUCTORS_ON_ARRAY_WHERE_NECESSARY_HPP_
#define RFL_PARSING_CALL_DESTRUCTORS_ON_ARRAY_WHERE_NECESSARY_HPP_

Expand Down
110 changes: 110 additions & 0 deletions src/modules/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
cmake_minimum_required(VERSION 3.28)

add_library(reflectcpp_module)

set(MODULE_FILES)

if(REFLECTCPP_JSON)
list(APPEND MODULE_FILES rfl.json.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_JSON)
endif()

if(REFLECTCPP_AVRO)
list(APPEND MODULE_FILES rfl.avro.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_AVRO)
endif()

if(REFLECTCPP_BSON)
list(APPEND MODULE_FILES rfl.bson.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_BSON)
endif()

if(REFLECTCPP_CAPNPROTO)
list(APPEND MODULE_FILES rfl.capnproto.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CAPNPROTO)
endif()

if(REFLECTCPP_CBOR)
list(APPEND MODULE_FILES rfl.cbor.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CBOR)
endif()

if(REFLECTCPP_CSV)
list(APPEND MODULE_FILES rfl.csv.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_CSV)
endif()

if(REFLECTCPP_FLEXBUFFERS)
list(APPEND MODULE_FILES rfl.flexbuf.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_FLEXBUFFERS)
endif()

if(REFLECTCPP_MSGPACK)
list(APPEND MODULE_FILES rfl.msgpack.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_MSGPACK)
endif()

if(REFLECTCPP_PARQUET)
list(APPEND MODULE_FILES rfl.parquet.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_PARQUET)
endif()

if(REFLECTCPP_TOML)
list(APPEND MODULE_FILES rfl.toml.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_TOML)
endif()

if(REFLECTCPP_UBJSON)
list(APPEND MODULE_FILES rfl.ubjson.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_UBJSON)
endif()

if(REFLECTCPP_XML)
list(APPEND MODULE_FILES rfl.xml.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_XML)
endif()

if(REFLECTCPP_YAML)
list(APPEND MODULE_FILES rfl.yaml.cppm)
target_compile_definitions(reflectcpp_module PUBLIC REFLECTCPP_YAML)
endif()

list(APPEND MODULE_FILES rfl.cppm)

target_sources(reflectcpp_module
PUBLIC
FILE_SET CXX_MODULES FILES ${MODULE_FILES}
)

target_compile_features(reflectcpp_module PUBLIC cxx_std_23)

target_include_directories(reflectcpp_module PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

target_link_libraries(reflectcpp_module PUBLIC reflectcpp::reflectcpp)

add_library(reflectcpp::module ALIAS reflectcpp_module)

# Installation
install(TARGETS reflectcpp_module
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/src/module
)

if (REFLECTCPP_BUILD_TESTS)
add_executable(reflect-cpp-modules-tests)
target_include_directories(reflect-cpp-modules-tests PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_sources(reflect-cpp-modules-tests PUBLIC "tests.cpp")
target_sources(reflect-cpp-modules-tests
PUBLIC
FILE_SET all_my_modules TYPE CXX_MODULES FILES ${MODULE_FILES}
)
endif()
30 changes: 30 additions & 0 deletions src/modules/rfl.avro.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module;

#ifdef REFLECTCPP_AVRO
#include "rfl/avro.hpp"
#include "rfl/avro/schema/Type.hpp"
#endif

export module rfl:avro;

export namespace rfl::avro {
#ifdef REFLECTCPP_AVRO
using rfl::avro::Parser;
using rfl::avro::Reader;
using rfl::avro::Schema;
using rfl::avro::Writer;
using rfl::avro::InputObjectType;
using rfl::avro::InputVarType;

using rfl::avro::load;
using rfl::avro::read;
using rfl::avro::save;
using rfl::avro::to_json_representation;
using rfl::avro::to_schema;
using rfl::avro::write;

namespace schema {
using rfl::avro::schema::Type;
}
#endif
}
22 changes: 22 additions & 0 deletions src/modules/rfl.bson.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module;

#ifdef REFLECTCPP_BSON
#include "rfl/bson.hpp"
#endif

export module rfl:bson;

export namespace rfl::bson {
#ifdef REFLECTCPP_BSON
using rfl::bson::Parser;
using rfl::bson::Reader;
using rfl::bson::Writer;
using rfl::bson::InputObjectType;
using rfl::bson::InputVarType;

using rfl::bson::load;
using rfl::bson::read;
using rfl::bson::save;
using rfl::bson::write;
#endif
}
41 changes: 41 additions & 0 deletions src/modules/rfl.capnproto.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module;

#ifdef REFLECTCPP_CAPNPROTO
#include "rfl/capnproto.hpp"
#include "rfl/capnproto/is_named_type.hpp"
#include "rfl/capnproto/schema/CapnProtoTypes.hpp"
#endif

export module rfl:capnproto;

export namespace rfl::capnproto {
#ifdef REFLECTCPP_CAPNPROTO
using rfl::capnproto::Parser;
using rfl::capnproto::Reader;
using rfl::capnproto::Schema;
using rfl::capnproto::SchemaImpl;
using rfl::capnproto::SchemaHolder;
using rfl::capnproto::Writer;
using rfl::capnproto::InputObjectType;
using rfl::capnproto::InputVarType;

using rfl::capnproto::load;
using rfl::capnproto::read;
using rfl::capnproto::save;
using rfl::capnproto::to_schema;
using rfl::capnproto::write;
using rfl::capnproto::get_root_name;
using rfl::capnproto::is_named_type;
using rfl::capnproto::to_string_representation;
using rfl::capnproto::to_schema;

namespace schema {
using rfl::capnproto::schema::CapnProtoTypes;
using rfl::capnproto::schema::Type;

using rfl::capnproto::schema::MAP_DEFINITION;

using rfl::capnproto::schema::operator<<;
}
#endif
}
Loading
Loading