Skip to content

Commit

Permalink
Added rfl::Tuple (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 authored Jul 28, 2024
1 parent d9387e2 commit 9c9ecea
Show file tree
Hide file tree
Showing 61 changed files with 1,297 additions and 563 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ In addition, it supports the following custom containers:
- `rfl::Ref`: Similar to `std::shared_ptr`, but (almost) guaranteed to never be null.
- `rfl::Result`: Allows for exception-free programming.
- `rfl::TaggedUnion`: Similar to `std::variant`, but with explicit tags that make parsing more efficient.
- `rfl::Tuple`: An alternative to `std::tuple` that compiles considerably faster.
- `rfl::Validator`: Allows for automatic input validation.
- `rfl::Variant`: An alternative to `std::variant` that compiles considerably faster.
Expand Down
4 changes: 3 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@

5.3) [rfl::NamedTuple](https://github.com/getml/reflect-cpp/blob/main/docs/named_tuple.md) - For structural typing.

5.4) [rfl::to_view](https://github.com/getml/reflect-cpp/blob/main/docs/to_view.md) - For accessing fields of a struct by index or name.
5.4) [rfl::Tuple](https://github.com/getml/reflect-cpp/blob/main/docs/rfl_tuple.md) - An alternative to `std::tuple` that compiles more quickly.

5.5) [rfl::to_view](https://github.com/getml/reflect-cpp/blob/main/docs/to_view.md) - For accessing fields of a struct by index or name.

## 6) Supported formats

Expand Down
3 changes: 2 additions & 1 deletion docs/named_tuple.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# `rfl::NamedTuple`

`rfl::NamedTuple` is very similar to `std::tuple`, but unlike `std::tuple`, the fields have names.
`rfl::NamedTuple` is very similar to `std::tuple` or `rfl::Tuple`, but unlike
these two structures, the fields have names.

In other words, consider the following struct:

Expand Down
16 changes: 16 additions & 0 deletions docs/rfl_tuple.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# `rfl::Tuple`

The problem with `std::tuple` is that it is recursively implemented. That is fine when you
have a small number of elements in your tuple, but as you increase the size of the tuple,
you will pay a price in terms of compile time.

That is why reflect-cpp contains `rfl::Tuple`, which in many ways behaves
just like `std::tuple`, but it compiles considerably faster.

The only downside of `rfl::Tuple` is that it cannot be used inside `constexpr` or `consteval`
functions.

You can use the functions `rfl::get`, `rfl::make_tuple`, `rfl::tuple_element_t`,
`rfl::tuple_size_v`, `rfl::tuple_cat` or `rfl::apply` to create or access the
tuple and they work the same way as their equivalents in the standard library.
In fact, `std::get` will also work on `rfl::Tuple`.
3 changes: 3 additions & 0 deletions include/rfl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "rfl/Validator.hpp"
#include "rfl/Variant.hpp"
#include "rfl/always_false.hpp"
#include "rfl/apply.hpp"
#include "rfl/as.hpp"
#include "rfl/comparisons.hpp"
#include "rfl/default.hpp"
Expand All @@ -51,6 +52,7 @@
#include "rfl/fields.hpp"
#include "rfl/from_named_tuple.hpp"
#include "rfl/get.hpp"
#include "rfl/make_from_tuple.hpp"
#include "rfl/make_named_tuple.hpp"
#include "rfl/name_t.hpp"
#include "rfl/named_tuple_t.hpp"
Expand All @@ -60,6 +62,7 @@
#include "rfl/replace.hpp"
#include "rfl/to_named_tuple.hpp"
#include "rfl/to_view.hpp"
#include "rfl/tuple_cat.hpp"
#include "rfl/type_name_t.hpp"
#include "rfl/visit.hpp"

Expand Down
3 changes: 2 additions & 1 deletion include/rfl/AddStructName.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "Field.hpp"
#include "Literal.hpp"
#include "apply.hpp"
#include "internal/StringLiteral.hpp"
#include "internal/get_type_name.hpp"
#include "internal/remove_namespaces.hpp"
Expand All @@ -23,7 +24,7 @@ struct AddStructName {
const auto add_new_field = [](auto&&... _fields) {
return make_named_tuple(FieldType(LiteralType()), std::move(_fields)...);
};
return std::apply(add_new_field, std::move(_view.fields()));
return rfl::apply(add_new_field, std::move(_view.fields()));
}
};

Expand Down
14 changes: 7 additions & 7 deletions include/rfl/Literal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
#include <utility>

#include "Result.hpp"
#include "Tuple.hpp"
#include "internal/StringLiteral.hpp"
#include "internal/no_duplicate_field_names.hpp"
#include "internal/nth_tuple_element_t.hpp"

namespace rfl {

Expand All @@ -24,7 +24,7 @@ struct LiteralHelper {

template <internal::StringLiteral... fields_>
class Literal {
using FieldsType = std::tuple<LiteralHelper<fields_>...>;
using FieldsType = rfl::Tuple<LiteralHelper<fields_>...>;

public:
using ValueType =
Expand Down Expand Up @@ -269,7 +269,7 @@ class Literal {

template <int _i>
static void allowed_strings_vec_add_one(std::vector<std::string>* _values) {
using FieldType = internal::nth_tuple_element_t<_i, FieldsType>;
using FieldType = tuple_element_t<_i, FieldsType>;
_values->emplace_back(FieldType::name_.str());
}

Expand All @@ -289,7 +289,7 @@ class Literal {
template <int _i>
void find_name_set_if_matches(std::string* _name) const {
if (_i == value_) {
using FieldType = internal::nth_tuple_element_t<_i, FieldsType>;
using FieldType = tuple_element_t<_i, FieldsType>;
*_name = FieldType::name_.str();
}
}
Expand All @@ -298,7 +298,7 @@ class Literal {
/// the string at compile time within the Literal's own fields.
template <int _i>
constexpr static auto find_name_within_own_fields() {
return internal::nth_tuple_element_t<_i, FieldsType>::name_;
return tuple_element_t<_i, FieldsType>::name_;
}

/// Finds the correct value associated with
Expand Down Expand Up @@ -326,7 +326,7 @@ class Literal {
template <int _i>
static void find_value_set_if_matches(const std::string& _str, bool* _found,
int* _idx) {
using FieldType = internal::nth_tuple_element_t<_i, FieldsType>;
using FieldType = tuple_element_t<_i, FieldsType>;
if (!*_found && FieldType::name_.string_view() == _str) {
*_idx = _i;
*_found = true;
Expand All @@ -339,7 +339,7 @@ class Literal {
if constexpr (_i == num_fields_) {
return -1;
} else {
using FieldType = internal::nth_tuple_element_t<_i, FieldsType>;
using FieldType = tuple_element_t<_i, FieldsType>;
if constexpr (FieldType::name_ == _name) {
return _i;
} else {
Expand Down
Loading

0 comments on commit 9c9ecea

Please sign in to comment.