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
35 changes: 28 additions & 7 deletions docs/custom_parser.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Custom parsers

## `rfl::Reflector`
## `rfl::Reflector`

If you absolutely do not want to make any changes to your original classes whatsoever,
You can create a Reflector template specialization for your type:
If you absolutely do not want to (or are unable to) make any changes to your
original classes whatsoever, you can create a Reflector template specialization
for your type:

```cpp
namespace rfl {
Expand All @@ -13,7 +14,7 @@ struct Reflector<Person> {
std::string first_name;
std::string last_name;
};

static Person to(const ReflType& v) noexcept {
return {v.first_name, v.last_name};
}
Expand All @@ -25,7 +26,27 @@ struct Reflector<Person> {
}
```

It's also fine to define just the `from` method when the original class is
One way to help make sure that your `ReflType` is kept up to date with your
original class is to use the `rfl::num_fields<T>` utility to implement a compile-
time assertion to verify that they have the same number of fields. The
`rfl::num_fields<T>` utility can be used even in cases where the original
class is too complex for `reflect-cpp`'s default reflection logic or
`rfl::to_view()` to be able to handle.

```cpp
namespace rfl {
template <>
struct Reflector<Person> {
struct ReflType {
std::string first_name;
std::string last_name;
};
static_assert(rfl::num_fields<ReflType> == rfl::num_fields<Person>,
"ReflType and actual type must have the same number of fields");
// ...
```

It's also fine to define just the `from` method when the original class is
only written, or `to` when the original class is only read:

```cpp
Expand All @@ -46,7 +67,7 @@ struct Reflector<Person> {
```

Note that the `ReflType` does not have to be a struct. For instance, if you have
a custom type called `MyCustomType` that you want to be serialized as a string,
a custom type called `MyCustomType` that you want to be serialized as a string,
you can do the following:

```cpp
Expand Down Expand Up @@ -114,7 +135,7 @@ struct Person {
};
```

You can then write a helper struct:
You can then write a helper struct:

```cpp
struct PersonImpl {
Expand Down
8 changes: 4 additions & 4 deletions docs/docs-readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@

[Standard containers](standard_containers.md) - Describes how reflect-cpp treats containers in the standard library.

[C arrays and inheritance](c_arrays_and_inheritance.md) - Describes how reflect-cpp handles C arrays and inheritance.
[C arrays and inheritance](c_arrays_and_inheritance.md) - Describes how reflect-cpp handles C arrays and inheritance.

[rfl::Bytestring](bytestring.md) - Describes how reflect-cpp handles binary strings for formats that support them.
[rfl::Bytestring](bytestring.md) - Describes how reflect-cpp handles binary strings for formats that support them.

[rfl::Binary, rfl::Hex and rfl::Oct](number_systems.md)- For expressing numbers in different formats.
[rfl::Binary, rfl::Hex and rfl::Oct](number_systems.md)- For expressing numbers in different formats.

## Validation

Expand All @@ -58,7 +58,7 @@

[Custom classes](concepts/custom_classes.md) - For custom classes with private fields.

[Custom parsers for your classes](custom_parser.md) - For custom classes with private fields that you want to leave absolutely untouched.
[Custom parsers for your classes](custom_parser.md) - For custom classes with private fields that you want (or need) to leave absolutely untouched.

## Useful helper functions and classes

Expand Down
14 changes: 14 additions & 0 deletions include/rfl/num_fields.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef RFL_NUM_FIELDS_HPP_
#define RFL_NUM_FIELDS_HPP_

#include "internal/num_fields.hpp"

namespace rfl {

/// Returns the number of fields fields.
template <class T>
constexpr std::size_t num_fields = internal::num_fields<T>;

} // namespace rfl

#endif
18 changes: 12 additions & 6 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
reflect-cpp uses vcpkg for dependency management, including
gtest, which is required for the tests.

```bash
# bootstrap vcpkg if you haven't done so already
```shell
# bootstrap vcpkg if you haven't done so already
git submodule update --init
./vcpkg/bootstrap-vcpkg.sh # Linux, macOS
./vcpkg/bootstrap-vcpkg.bat # Windows
Expand All @@ -15,29 +15,35 @@ git submodule update --init

To compile the tests, do the following:

```bash
```shell
cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DREFLECTCPP_BUILD_TESTS=ON
cmake --build build -j 4 # gcc, clang
cmake --build build --config Release -j 4 # MSVC
```

To run the tests, do the following:

```
```shell
./build/tests/json/reflect-cpp-json-tests
```

## All serialization formats

To compile the tests with serialization formats other than JSON, do the following:

```bash
```shell
cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_AVRO=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_CAPNPROTO=ON -DREFLECTCPP_CBOR=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_MSGPACK=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_TOML=ON -DREFLECTCPP_UBJSON=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
Comment thread
liuzicheng1987 marked this conversation as resolved.
cmake --build build -j 4 # gcc, clang
cmake --build build --config Release -j 4 # MSVC
```

To run the tests, do the following:
You can run all of the tests via `ctest`, as in:

```shell
ctest --test-dir build --output-on-failure
```

Or you can run tests individually, as in:

```
./build/tests/avro/reflect-cpp-avro-tests
Expand Down
13 changes: 9 additions & 4 deletions tests/json_c_arrays_and_inheritance/test_inheritance2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <iostream>
#include <rfl.hpp>

#include "rfl/internal/num_fields.hpp"
#include "rfl/num_fields.hpp"

namespace test_inheritance2 {

Expand All @@ -31,23 +31,28 @@ struct EmptyDerived2 : EmptyBase1, EmptyBase2, BaseX {};
TEST(json, test_inheritance2) {
Derived1 derived1;
const auto derived1_view = rfl::to_view(derived1);
static_assert(rfl::num_fields<Derived1> == 2);
static_assert(derived1_view.size() == 2);

Derived2 derived2;
const auto derived2_view = rfl::to_view(derived2);
static_assert(rfl::num_fields<Derived2> == 3);
static_assert(derived2_view.size() == 3);

EmptyDerived1 empty_derived0;
EmptyDerived0 empty_derived0;
auto empty_derived0_view = rfl::to_view(empty_derived0);
static_assert(rfl::num_fields<EmptyDerived0> == 2);
static_assert(empty_derived0_view.size() == 2);

EmptyDerived1 empty_derived1;
auto empty_derived1_view = rfl::to_view(empty_derived1);
static_assert(rfl::num_fields<EmptyDerived1> == 2);
static_assert(empty_derived1_view.size() == 2);

EmptyDerived1 empty_derived2;
EmptyDerived2 empty_derived2;
auto empty_derived2_view = rfl::to_view(empty_derived2);
static_assert(empty_derived0_view.size() == 2);
static_assert(rfl::num_fields<EmptyDerived1> == 2);
static_assert(empty_derived2_view.size() == 2);

EXPECT_TRUE(true);
}
Expand Down
Loading