Skip to content
Merged
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
109 changes: 72 additions & 37 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.23)

option(REFLECTCPP_BUILD_SHARED "Build shared library" ${BUILD_SHARED_LIBS})

option(REFLECTCPP_JSON "Enable JSON support" ON) # enabled by default
option(REFLECTCPP_BSON "Enable BSON support" OFF)
option(REFLECTCPP_CBOR "Enable CBOR support" OFF)
option(REFLECTCPP_FLEXBUFFERS "Enable flexbuffers support" OFF)
Expand All @@ -17,6 +18,7 @@ option(REFLECTCPP_USE_BUNDLED_DEPENDENCIES "Use the bundled dependencies" ON)

set(REFLECTCPP_USE_VCPKG_DEFAULT OFF)
if(REFLECTCPP_BUILD_BENCHMARKS)
set(REFLECTCPP_JSON ON CACHE BOOL "" FORCE)
set(REFLECTCPP_BSON ON CACHE BOOL "" FORCE)
set(REFLECTCPP_CBOR ON CACHE BOOL "" FORCE)
set(REFLECTCPP_FLEXBUFFERS ON CACHE BOOL "" FORCE)
Expand All @@ -25,7 +27,9 @@ if(REFLECTCPP_BUILD_BENCHMARKS)
set(REFLECTCPP_TOML ON CACHE BOOL "" FORCE)
set(REFLECTCPP_YAML ON CACHE BOOL "" FORCE)
endif()
if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR REFLECTCPP_BSON OR REFLECTCPP_CBOR OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_XML OR REFLECTCPP_TOML OR REFLECTCPP_YAML)
if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR
(REFLECTCPP_JSON AND NOT REFLECTCPP_USE_BUNDLED_DEPENDENCIES) OR
REFLECTCPP_BSON OR REFLECTCPP_CBOR OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_XML OR REFLECTCPP_TOML OR REFLECTCPP_YAML)
# enable vcpkg per default if require features other than JSON
set(REFLECTCPP_USE_VCPKG_DEFAULT ON)
endif()
Expand All @@ -40,58 +44,71 @@ project(reflectcpp LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)

if(REFLECTCPP_USE_BUNDLED_DEPENDENCIES)
if (REFLECTCPP_BUILD_SHARED)
add_library(reflectcpp SHARED)
else()
add_library(reflectcpp STATIC)
endif()

target_sources(reflectcpp PRIVATE src/reflectcpp.cpp src/yyjson.c)
set_source_files_properties(src/yyjson.c PROPERTIES LANGUAGE CXX)
if (REFLECTCPP_BUILD_SHARED)
add_library(reflectcpp SHARED)
else()
add_library(reflectcpp STATIC)
endif()

target_compile_features(reflectcpp PUBLIC cxx_std_20)
if (MSVC)
target_compile_options(reflectcpp PRIVATE $<$<CONFIG:Debug>:-Wall>)
else()
target_compile_options(reflectcpp PRIVATE $<$<CONFIG:Debug>:-Wall -Wextra>)
endif()

if (MSVC)
target_compile_options(reflectcpp PRIVATE $<$<CONFIG:Debug>:-Wall>)
else()
target_compile_options(reflectcpp PRIVATE $<$<CONFIG:Debug>:-Wall -Wextra>)
endif()
target_compile_features(reflectcpp PUBLIC cxx_std_20)

target_include_directories(
reflectcpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/rfl/thirdparty>)
else()
if (REFLECTCPP_BUILD_SHARED)
add_library(reflectcpp SHARED)
else()
add_library(reflectcpp STATIC)
endif()
set(REFLECT_CPP_SOURCES
src/reflectcpp.cpp
)

target_sources(reflectcpp PRIVATE src/reflectcpp.cpp)
target_include_directories(
reflectcpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

if (REFLECTCPP_USE_BUNDLED_DEPENDENCIES)
target_include_directories(
reflectcpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

target_compile_features(reflectcpp PUBLIC cxx_std_20)

$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/rfl/thirdparty>)
else ()
find_package(ctre CONFIG REQUIRED)
find_package(yyjson CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE ctre::ctre yyjson::yyjson)
endif()
target_link_libraries(reflectcpp INTERFACE ctre::ctre)
endif ()

set_target_properties(reflectcpp PROPERTIES LINKER_LANGUAGE CXX)
if (REFLECTCPP_JSON)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_json.cpp
)
if (REFLECTCPP_USE_BUNDLED_DEPENDENCIES)
list(APPEND REFLECT_CPP_SOURCES
src/yyjson.c
)
set_source_files_properties(src/yyjson.c PROPERTIES LANGUAGE CXX)

target_include_directories(
reflectcpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/rfl/thirdparty>)
else ()
find_package(yyjson CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE yyjson::yyjson)
endif ()
endif ()

if (REFLECTCPP_BSON)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_bson.cpp
)
find_package(bson-1.0 CONFIG REQUIRED)
target_link_libraries(reflectcpp PRIVATE $<IF:$<TARGET_EXISTS:mongo::bson_static>,mongo::bson_static,mongo::bson_shared>)
endif ()

if (REFLECTCPP_CBOR)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_cbor.cpp
)
target_include_directories(reflectcpp SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")
target_include_directories(reflectcpp SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/tinycbor")
if (MSVC)
target_link_libraries(reflectcpp PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/tinycbor${CMAKE_STATIC_LIBRARY_SUFFIX}")
else ()
Expand All @@ -100,11 +117,17 @@ if (REFLECTCPP_CBOR)
endif ()

if (REFLECTCPP_FLEXBUFFERS)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_flexbuf.cpp
)
find_package(flatbuffers CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE flatbuffers::flatbuffers)
endif ()

if (REFLECTCPP_MSGPACK)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_msgpack.cpp
)
find_package(msgpack-c CONFIG REQUIRED)
if (MSVC)
target_link_libraries(reflectcpp PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/msgpack-c${CMAKE_STATIC_LIBRARY_SUFFIX}")
Expand All @@ -114,6 +137,9 @@ if (REFLECTCPP_MSGPACK)
endif ()

if (REFLECTCPP_TOML)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_toml.cpp
)
if (MSVC)
target_link_libraries(reflectcpp PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/tomlplusplus${CMAKE_STATIC_LIBRARY_SUFFIX}")
else ()
Expand All @@ -122,15 +148,24 @@ if (REFLECTCPP_TOML)
endif()

if (REFLECTCPP_XML)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_xml.cpp
)
find_package(pugixml CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE pugixml::pugixml)
endif ()

if (REFLECTCPP_YAML)
list(APPEND REFLECT_CPP_SOURCES
src/reflectcpp_yaml.cpp
)
find_package(yaml-cpp CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE yaml-cpp::yaml-cpp)
endif ()

set_target_properties(reflectcpp PROPERTIES LINKER_LANGUAGE CXX)
target_sources(reflectcpp PRIVATE ${REFLECT_CPP_SOURCES})

if (REFLECTCPP_BUILD_TESTS)
if (MSVC)
set(REFLECT_CPP_GTEST_LIB "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,10 +527,13 @@ The following compilers are supported:

### Option 1: Include source files into your own build

Simply copy the contents of the folder `include` into your source repository or add it to your include path and also add `src/reflectcpp.cpp` and `src/yyjson.c` to your source files for compilation.
If you don't need JSON support or want to link to your own version of YYJSON, then only copy `src/reflectcpp.cpp`.
Simply copy the contents of the folders `include` and `src` into your source repository or add it to your include path
and also add `src/reflectcpp.cpp` and `src/reflectcpp_json.cpp` and `src/yyjson.c` to your source files for compilation.
If you want to link to your own version of YYJSON, then only copy `src/reflectcpp.cpp` and `src/reflectcpp_json.cpp`.
If you don't need JSON support, then only copy `src/reflectcpp.cpp`.

If you need support for other serialization formats like flexbuffers or XML, you should also include and link the respective libraries, as listed in the section on serialization formats.
If you need support for other serialization formats like flexbuffers or XML, you should also add `src/reflectcpp_<format>.cpp`
and include and link the respective libraries, as listed in the section on serialization formats.

### Option 2: Compilation using cmake

Expand Down
1 change: 0 additions & 1 deletion include/rfl/bson/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ template <class R, class W, class ProcessorsType>
requires AreReaderAndWriter<R, W, bson_oid_t>
struct Parser<R, W, ProcessorsType, bson_oid_t> {
using InputVarType = typename R::InputVarType;
using OutputVarType = typename W::OutputVarType;

using ParentType = Parent<W>;

Expand Down
65 changes: 7 additions & 58 deletions include/rfl/bson/Reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,49 +50,12 @@ struct Reader {
});

rfl::Result<InputVarType> get_field_from_array(
const size_t _idx, const InputArrayType& _arr) const noexcept {
bson_t b;
bson_iter_t iter;
const auto doc = _arr.val_->value.v_doc;
if (bson_init_static(&b, doc.data, doc.data_len)) {
if (bson_iter_init(&iter, &b)) {
size_t i = 0;
while (bson_iter_next(&iter)) {
if (i == _idx) {
return to_input_var(&iter);
}
++i;
}
} else {
return Error("Could not init the array iteration.");
}
} else {
return Error("Could not init array.");
}
return Error("Index " + std::to_string(_idx) + " of of bounds.");
}
const size_t _idx, const InputArrayType& _arr) const noexcept;

rfl::Result<InputVarType> get_field_from_object(
const std::string& _name, const InputObjectType& _obj) const noexcept {
bson_t b;
bson_iter_t iter;
const auto doc = _obj.val_->value.v_doc;
if (bson_init_static(&b, doc.data, doc.data_len)) {
if (bson_iter_init(&iter, &b)) {
while (bson_iter_next(&iter)) {
auto key = std::string(bson_iter_key(&iter));
if (key == _name) {
return to_input_var(&iter);
}
}
}
}
return Error("No field named '" + _name + "' was found.");
}
const std::string& _name, const InputObjectType& _obj) const noexcept;

bool is_empty(const InputVarType& _var) const noexcept {
return _var.val_->value_type == BSON_TYPE_NULL;
}
bool is_empty(const InputVarType& _var) const noexcept;

template <class T>
rfl::Result<T> to_basic_type(const InputVarType& _var) const noexcept {
Expand Down Expand Up @@ -159,13 +122,7 @@ struct Reader {
}

rfl::Result<InputArrayType> to_array(
const InputVarType& _var) const noexcept {
const auto btype = _var.val_->value_type;
if (btype != BSON_TYPE_ARRAY && btype != BSON_TYPE_DOCUMENT) {
return Error("Could not cast to an array.");
}
return InputArrayType{_var.val_};
}
const InputVarType& _var) const noexcept;

template <class ArrayReader>
std::optional<Error> read_array(const ArrayReader& _array_reader,
Expand Down Expand Up @@ -212,13 +169,7 @@ struct Reader {
}

rfl::Result<InputObjectType> to_object(
const InputVarType& _var) const noexcept {
const auto btype = _var.val_->value_type;
if (btype != BSON_TYPE_DOCUMENT) {
return Error("Could not cast to a document.");
}
return InputObjectType{_var.val_};
}
const InputVarType& _var) const noexcept;

template <class T>
rfl::Result<T> use_custom_constructor(
Expand All @@ -231,12 +182,10 @@ struct Reader {
}

private:
InputVarType to_input_var(bson_iter_t* _iter) const noexcept {
return InputVarType{bson_iter_value(_iter)};
}
InputVarType to_input_var(bson_iter_t* _iter) const noexcept;
};

} // namespace bson
} // namespace rfl

#endif // JSON_PARSER_HPP_
#endif
Loading
Loading