lots of stuff

This commit is contained in:
Mars 2024-05-31 22:59:00 -04:00
parent e8fb8ec19f
commit 791e237470
Signed by: pupbrained
GPG key ID: 874E22DF2F9DFCB5
224 changed files with 19811 additions and 129 deletions

View file

@ -0,0 +1,33 @@
#ifndef RFL_INTERNAL_ARRAY_HPP_
#define RFL_INTERNAL_ARRAY_HPP_
#include <array>
#include <cstddef>
#include <type_traits>
#include "to_std_array.hpp"
namespace rfl {
namespace internal {
template <class T>
requires std::is_array_v<T>
struct Array {
using Type = T;
using StdArrayType = to_std_array_t<T>;
Array() = default;
Array(const StdArrayType &_arr) : arr_(_arr) {}
Array(StdArrayType &&_arr) : arr_(std::move(_arr)) {}
Array(const T &_arr) : arr_(to_std_array(_arr)) {}
Array(T &&_arr) : arr_(to_std_array(_arr)) {}
~Array() = default;
StdArrayType arr_;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,20 @@
#ifndef RFL_INTERNAL_FIELD_TUPLE_T_HPP_
#define RFL_INTERNAL_FIELD_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "copy_to_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using field_tuple_t =
typename std::invoke_result<decltype(copy_to_field_tuple<T>), T>::type;
}
} // namespace rfl
#endif

View file

@ -0,0 +1,23 @@
#ifndef RFL_INTERNAL_FIELDS_HPP_
#define RFL_INTERNAL_FIELDS_HPP_
#include <array>
#include <cstdint>
#include <string>
#include <string_view>
#include <unordered_map>
namespace rfl {
namespace internal {
template <int N>
struct Fields {
std::array<std::string, N> names_;
std::unordered_map<std::string_view, std::int16_t> indices_;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,156 @@
#ifndef RFL_INTERNAL_GETTER_HPP_
#define RFL_INTERNAL_GETTER_HPP_
#include <tuple>
#include <variant>
#include "StringLiteral.hpp"
#include "find_index.hpp"
namespace rfl::internal {
// ----------------------------------------------------------------------------
template <class NamedTupleType>
struct Getter;
// ----------------------------------------------------------------------------
/// Default case - anything that cannot be explicitly matched.
template <class NamedTupleType>
struct Getter {
public:
/// Retrieves the indicated value from the tuple.
template <int _index>
static inline auto& get(NamedTupleType& _tup) {
return std::get<_index>(_tup.values());
}
/// Gets a field by name.
template <StringLiteral _field_name>
static inline auto& get(NamedTupleType& _tup) {
constexpr auto index =
find_index<_field_name, typename NamedTupleType::Fields>();
return Getter<NamedTupleType>::template get<index>(_tup);
}
/// Gets a field by the field type.
template <class Field>
static inline auto& get(NamedTupleType& _tup) {
constexpr auto index =
find_index<Field::name_, typename NamedTupleType::Fields>();
static_assert(
std::is_same<typename std::tuple_element<
index, typename NamedTupleType::Fields>::type::Type,
typename Field::Type>(),
"If two fields have the same name, "
"their type must be the same as "
"well.");
return Getter<NamedTupleType>::template get<index>(_tup);
}
/// Retrieves the indicated value from the tuple.
template <int _index>
static inline const auto& get_const(const NamedTupleType& _tup) {
return std::get<_index>(_tup.values());
}
/// Gets a field by name.
template <StringLiteral _field_name>
static inline const auto& get_const(const NamedTupleType& _tup) {
constexpr auto index =
find_index<_field_name, typename NamedTupleType::Fields>();
return Getter<NamedTupleType>::template get_const<index>(_tup);
}
/// Gets a field by the field type.
template <class Field>
static inline const auto& get_const(const NamedTupleType& _tup) {
constexpr auto index =
find_index<Field::name_, typename NamedTupleType::Fields>();
static_assert(
std::is_same<typename std::tuple_element<
index, typename NamedTupleType::Fields>::type::Type,
typename Field::Type>(),
"If two fields have the same name, "
"their type must be the same as "
"well.");
return Getter<NamedTupleType>::template get_const<index>(_tup);
}
};
// ----------------------------------------------------------------------------
/// For handling std::variant.
template <class... NamedTupleTypes>
struct Getter<std::variant<NamedTupleTypes...>> {
public:
/// Retrieves the indicated value from the tuple.
template <int _index>
static inline auto& get(std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](auto& _t) -> auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_t)>;
return Getter<NamedTupleType>::template get<_index>(_t);
};
return std::visit(apply, _tup);
}
/// Gets a field by name.
template <StringLiteral _field_name>
static inline auto& get(std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](auto& _t) -> auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_t)>;
return Getter<NamedTupleType>::template get<_field_name>(_t);
};
return std::visit(apply, _tup);
}
/// Gets a field by the field type.
template <class Field>
static inline auto& get(std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](auto& _t) -> auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_t)>;
return Getter<NamedTupleType>::template get<Field>(_t);
};
return std::visit(apply, _tup);
}
/// Retrieves the indicated value from the tuple.
template <int _index>
static inline const auto& get_const(
const std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](const auto& _tup) -> const auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_tup)>;
return Getter<NamedTupleType>::template get_const<_index>(_tup);
};
return std::visit(apply, _tup);
}
/// Gets a field by name.
template <StringLiteral _field_name>
static inline const auto& get_const(
const std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](const auto& _t) -> const auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_t)>;
return Getter<NamedTupleType>::template get_const<_field_name>(_t);
};
return std::visit(apply, _tup);
}
/// Gets a field by the field type.
template <class Field>
static inline const auto& get_const(
const std::variant<NamedTupleTypes...>& _tup) {
const auto apply = [](const auto& _t) -> const auto& {
using NamedTupleType = std::remove_cvref_t<decltype(_t)>;
return Getter<NamedTupleType>::template get_const<Field>(_t);
};
return std::visit(apply, _tup);
}
};
// ----------------------------------------------------------------------------
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,19 @@
#ifndef RFL_INTERNAL_HASVALIDATION_HPP_
#define RFL_INTERNAL_HASVALIDATION_HPP_
#include <type_traits>
#include "../Result.hpp"
namespace rfl {
namespace internal {
template <class Class, typename T>
concept HasValidation = requires(Class obj, T value) {
{ Class::validate(value) } -> std::same_as<rfl::Result<T>>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,53 @@
#ifndef RFL_INTERNAL_MEMOIZATION_HPP_
#define RFL_INTERNAL_MEMOIZATION_HPP_
#include <atomic>
#include <mutex>
namespace rfl {
namespace internal {
/// For a thread-safe memoization pattern.
template <class T>
class Memoization {
public:
Memoization() { flag_.clear(); }
~Memoization() = default;
public:
/// Returns the underlying value.
template <class F>
const T& value(const F& _f) {
if (flag_.test()) {
return value_;
}
std::lock_guard<std::mutex> guard(mtx_);
if (flag_.test()) {
return value_;
}
_f(&value_);
flag_.test_and_set();
return value_;
}
private:
/// Signifies whether t_ has been set.
std::atomic_flag flag_;
/// A mutex, only needed for writing.
std::mutex mtx_;
/// The type to be initialized.
T value_;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,146 @@
#ifndef RFL_INTERNAL_SKIP_HPP_
#define RFL_INTERNAL_SKIP_HPP_
#include <optional>
namespace rfl::internal {
template <class T, bool _skip_serialization, bool _skip_deserialization>
class Skip {
private:
using SelfType = Skip<T, _skip_serialization, _skip_deserialization>;
public:
static constexpr bool skip_serialization_ = _skip_serialization;
static constexpr bool skip_deserialization_ = _skip_deserialization;
/// The underlying type.
using Type = T;
using ReflectionType = std::optional<T>;
Skip() : value_(Type()) {}
Skip(const Type& _value) : value_(_value) {}
Skip(ReflectionType&& _value) noexcept
: value_(_value ? std::move(*_value) : Type()) {}
Skip(const ReflectionType& _value) : value_(_value ? *_value : Type()) {}
Skip(Type&& _value) noexcept : value_(std::move(_value)) {}
Skip(SelfType&& _skip) noexcept = default;
Skip(const SelfType& _skip) = default;
template <class U, bool _skip_s, bool _skip_d>
Skip(const Skip<U, _skip_s, _skip_d>& _other) : value_(_other.get()) {}
template <class U, bool _skip_s, bool _skip_d>
Skip(Skip<U, _skip_s, _skip_d>&& _other) : value_(_other.get()) {}
template <class U, typename std::enable_if<std::is_convertible_v<U, Type>,
bool>::type = true>
Skip(const U& _value) : value_(_value) {}
template <class U, typename std::enable_if<std::is_convertible_v<U, Type>,
bool>::type = true>
Skip(U&& _value) noexcept : value_(std::forward<U>(_value)) {}
template <class U, bool _skip_s, bool _skip_d,
typename std::enable_if<std::is_convertible_v<U, Type>,
bool>::type = true>
Skip(const Skip<U, _skip_s, _skip_d>& _skip) : value_(_skip.value()) {}
/// Assigns the underlying object to its default value.
template <class U = Type,
typename std::enable_if<std::is_default_constructible_v<U>,
bool>::type = true>
Skip(const Default& _default) : value_(Type()) {}
~Skip() = default;
/// Returns the underlying object.
Type& get() { return value_; }
/// Returns the underlying object.
const Type& get() const { return value_; }
/// Returns the underlying object.
Type& operator()() { return value_; }
/// Returns the underlying object.
const Type& operator()() const { return value_; }
/// Assigns the underlying object.
auto& operator=(const Type& _value) {
value_ = _value;
return *this;
}
/// Assigns the underlying object.
auto& operator=(Type&& _value) noexcept {
value_ = std::move(_value);
return *this;
}
/// Assigns the underlying object.
template <class U, typename std::enable_if<std::is_convertible_v<U, Type>,
bool>::type = true>
auto& operator=(const U& _value) {
value_ = _value;
return *this;
}
/// Assigns the underlying object to its default value.
template <class U = Type,
typename std::enable_if<std::is_default_constructible_v<U>,
bool>::type = true>
auto& operator=(const Default& _default) {
value_ = Type();
return *this;
}
/// Assigns the underlying object.
SelfType& operator=(const SelfType& _other) = default;
/// Assigns the underlying object.
SelfType& operator=(SelfType&& _other) = default;
/// Assigns the underlying object.
template <class U, bool _skip_s, bool _skip_d>
auto& operator=(const Skip<U, _skip_s, _skip_d>& _skip) {
value_ = _skip.get();
return *this;
}
/// Assigns the underlying object.
template <class U, bool _skip_s, bool _skip_d>
auto& operator=(Skip<U, _skip_s, _skip_d>&& _skip) {
value_ = std::forward<T>(_skip.value_);
return *this;
}
/// Returns the ReflectionType - necessary for the serialization to work.
ReflectionType reflection() const { return value_; }
/// Assigns the underlying object.
void set(const Type& _value) { value_ = _value; }
/// Assigns the underlying object.
void set(Type&& _value) { value_ = std::move(_value); }
/// Returns the underlying object.
Type& value() { return value_; }
/// Returns the underlying object.
const Type& value() const { return value_; }
private:
/// The underlying value
T value_;
};
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,54 @@
#ifndef RFL_INTERNAL_STRINGLITERAL_HPP_
#define RFL_INTERNAL_STRINGLITERAL_HPP_
#include <algorithm>
#include <array>
#include <string>
#include <string_view>
namespace rfl {
namespace internal {
/// Normal strings cannot be used as template
/// parameters, but this can. This is needed
/// for the parameters names in the NamedTuples.
template <size_t N>
struct StringLiteral {
constexpr StringLiteral(const auto... _chars) : arr_{_chars..., '\0'} {}
constexpr StringLiteral(const std::array<char, N> _arr) : arr_(_arr) {}
constexpr StringLiteral(const char (&_str)[N]) {
std::copy_n(_str, N, std::data(arr_));
}
/// Returns the value as a string.
std::string str() const { return std::string(std::data(arr_), N - 1); }
/// Returns the value as a string.
constexpr std::string_view string_view() const {
return std::string_view(std::data(arr_), N - 1);
}
std::array<char, N> arr_{};
};
template <size_t N1, size_t N2>
constexpr inline bool operator==(const StringLiteral<N1>& _first,
const StringLiteral<N2>& _second) {
if constexpr (N1 != N2) {
return false;
}
return _first.string_view() == _second.string_view();
}
template <size_t N1, size_t N2>
constexpr inline bool operator!=(const StringLiteral<N1>& _first,
const StringLiteral<N2>& _second) {
return !(_first == _second);
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_VISITTREE_HPP_
#define RFL_INTERNAL_VISITTREE_HPP_
namespace rfl {
namespace internal {
struct VisitTree {
/// Evaluates a visitor pattern using a tree-like structure.
template <int _begin, int _end, class Visitor, class... Args>
static inline auto visit(const auto& _v, const int _i,
const Args&... _args) {
static_assert(_end > _begin, "_end needs to be greater than _begin.");
if constexpr (_end - _begin == 1) {
return _v.template visit<_begin>(_args...);
} else {
constexpr int middle = (_begin + _end) / 2;
if (_i < middle) {
return visit<_begin, middle, Visitor>(_v, _i, _args...);
} else {
return visit<middle, _end, Visitor>(_v, _i, _args...);
}
}
}
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,27 @@
#ifndef RFL_INTERNAL_VISITORWRAPPER_HPP_
#define RFL_INTERNAL_VISITORWRAPPER_HPP_
#include "../Literal.hpp"
#include "../TaggedUnion.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
/// Necessary for the VisitTree structure.
template <class Visitor, internal::StringLiteral... _fields>
struct VisitorWrapper {
/// Calls the underlying visitor when required to do so.
template <int _i, class... Args>
inline auto visit(const Args&... _args) const {
return (*visitor_)(name_of<Literal<_fields...>, _i>(), _args...);
}
/// The underlying visitor.
const Visitor* visitor_;
};
} // namespace internal
} // namespace rfl
#endif // RFL_VISIT_HPP_

View file

@ -0,0 +1,26 @@
#ifndef RFL_INTERNAL_ALLFIELDS_HPP_
#define RFL_INTERNAL_ALLFIELDS_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "is_field.hpp"
namespace rfl {
namespace internal {
template <class TupleType, int _i = 0>
constexpr bool all_fields() {
if constexpr (_i == std::tuple_size_v<TupleType>) {
return true;
} else {
using T = std::tuple_element_t<_i, TupleType>;
return is_field_v<T> && all_fields<TupleType, _i + 1>();
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,584 @@
#ifndef RFL_INTERNAL_BIND_FAKE_OBJECT_TO_TUPLE_HPP_
#define RFL_INTERNAL_BIND_FAKE_OBJECT_TO_TUPLE_HPP_
#include <cstddef>
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
#include "../always_false.hpp"
#include "get_fake_object.hpp"
#include "num_fields.hpp"
namespace rfl {
namespace internal {
template <class T, std::size_t n>
struct fake_object_tuple_view_helper {
static consteval auto tuple_view() {
static_assert(
rfl::always_false_v<T>,
"\n\nThis error occurs for one of two reasons:\n\n"
"1) You have created a struct with more than 100 fields, which is "
"unsupported. Please split up your struct into several "
"smaller structs and then use rfl::Flatten<...> to combine them. "
"Refer "
"to the documentation on rfl::Flatten<...> for details.\n\n"
"2) You have added a custom constructor to your struct, which you "
"shouldn't do either. Please refer to the sections on custom "
"classes or custom parsers in the documentation "
"for solutions to this problem.\n\n");
}
};
template <class T>
struct fake_object_tuple_view_helper<T, 0> {
static consteval auto tuple_view() { return std::tie(); }
};
#define RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(n, ...) \
template <class T> \
struct fake_object_tuple_view_helper<T, n> { \
static consteval auto tuple_view() { \
const auto& [__VA_ARGS__] = get_fake_object<std::remove_cvref_t<T>>(); \
const auto ref_tup = std::tie(__VA_ARGS__); \
const auto get_ptrs = [](const auto&... _refs) { \
return std::make_tuple(&_refs...); \
}; \
return std::apply(get_ptrs, ref_tup); \
} \
}
/*The following boilerplate code was generated using a Python script:
macro = "RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER"
with open("generated_code4.cpp", "w", encoding="utf-8") as codefile:
codefile.write(
"\n".join(
[
f"{macro}({i}, {', '.join([f'f{j}' for j in range(i)])});"
for i in range(1, 101)
]
)
)
*/
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(1, f0);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(2, f0, f1);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(3, f0, f1, f2);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(4, f0, f1, f2, f3);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(5, f0, f1, f2, f3, f4);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(6, f0, f1, f2, f3, f4, f5);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(7, f0, f1, f2, f3, f4, f5,
f6);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(8, f0, f1, f2, f3, f4, f5, f6,
f7);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(9, f0, f1, f2, f3, f4, f5, f6,
f7, f8);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(10, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(11, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(12, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(13, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11,
f12);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(14, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(15, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(16, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(17, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(18, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(19, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(20, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(21, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(22, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(23, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(24, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(25, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(26, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(27, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(28, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(29, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(30, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(31, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(32, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(33, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31, f32);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(34, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31, f32, f33);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(35, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(36, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(37, f0, f1, f2, f3, f4, f5,
f6, f7, f8, f9, f10, f11, f12,
f13, f14, f15, f16, f17, f18,
f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
38, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
39, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
40, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
41, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
42, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
43, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
44, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
45, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
46, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
47, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
48, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
49, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
50, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
51, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
52, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
53, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
54, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
55, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
56, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
57, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
58, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
59, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
60, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
61, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
62, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
63, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
64, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
65, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
66, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
67, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
68, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
69, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
70, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
71, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
72, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
73, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
74, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
75, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
76, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
77, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
78, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
79, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
80, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
81, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
82, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
83, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
84, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
85, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
86, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
87, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
88, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
89, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
90, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
91, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
92, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
93, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
94, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
95, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
96, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
97, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
98, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
99, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97, f98);
RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER(
100, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97, f98, f99);
#undef RFL_INTERNAL_DEFINE_FAKE_OBJECT_TUPLE_VIEW_HELPER
template <class T>
consteval auto bind_fake_object_to_tuple() {
return fake_object_tuple_view_helper<T, num_fields<T>>::tuple_view();
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,603 @@
#ifndef RFL_INTERNAL_BIND_TO_TUPLE_HPP_
#define RFL_INTERNAL_BIND_TO_TUPLE_HPP_
#include <cstddef>
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
#include "../always_false.hpp"
#include "is_named_tuple.hpp"
#include "num_fields.hpp"
namespace rfl {
namespace internal {
template <std::size_t n>
struct tuple_view_helper {
template <class T>
static constexpr auto tuple_view(T&) {
static_assert(
rfl::always_false_v<T>,
"\n\nThis error occurs for one of two reasons:\n\n"
"1) You have created a struct with more than 100 fields, which is "
"unsupported. Please split up your struct into several "
"smaller structs and then use rfl::Flatten<...> to combine them. "
"Refer "
"to the documentation on rfl::Flatten<...> for details.\n\n"
"2) You have added a custom constructor to your struct, which you "
"shouldn't do either. Please refer to the sections on custom "
"classes or custom parsers in the documentation "
"for solutions to this problem.\n\n");
}
};
template <>
struct tuple_view_helper<0> {
static constexpr auto tuple_view(auto&) { return std::tie(); }
};
#define RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(n, ...) \
template <> \
struct tuple_view_helper<n> { \
static constexpr auto tuple_view(auto& t) { \
auto& [__VA_ARGS__] = t; \
return std::tie(__VA_ARGS__); \
} \
}
/*The following boilerplate code was generated using a Python script:
macro = "RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER"
with open("generated_code4.cpp", "w", encoding="utf-8") as codefile:
codefile.write(
"\n".join(
[
f"{macro}({i}, {', '.join([f'f{j}' for j in range(i)])});"
for i in range(1, 101)
]
)
)
*/
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(1, f0);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(2, f0, f1);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(3, f0, f1, f2);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(4, f0, f1, f2, f3);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(5, f0, f1, f2, f3, f4);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(6, f0, f1, f2, f3, f4, f5);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(7, f0, f1, f2, f3, f4, f5, f6);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(8, f0, f1, f2, f3, f4, f5, f6, f7);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(9, f0, f1, f2, f3, f4, f5, f6, f7, f8);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(10, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(11, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(12, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(13, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(14, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(15, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(16, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(17, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(18, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(19, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(20, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(21, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(22, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(23, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(24, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(25, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(26, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(27, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(28, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(29, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(30, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(31, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(32, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(33, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(34, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(35, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(36, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(37, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(38, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(39, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(40, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(41, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(42, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(43, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(44, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(45, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(46, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(47, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(48, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(49, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(50, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(51, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(52, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(53, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(54, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(55, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(56, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(57, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55, f56);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
58, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
59, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
60, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
61, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(62, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55, f56,
f57, f58, f59, f60, f61);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(63, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55, f56,
f57, f58, f59, f60, f61, f62);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(64, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55, f56,
f57, f58, f59, f60, f61, f62, f63);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(65, f0, f1, f2, f3, f4, f5, f6, f7, f8,
f9, f10, f11, f12, f13, f14, f15, f16,
f17, f18, f19, f20, f21, f22, f23, f24,
f25, f26, f27, f28, f29, f30, f31, f32,
f33, f34, f35, f36, f37, f38, f39, f40,
f41, f42, f43, f44, f45, f46, f47, f48,
f49, f50, f51, f52, f53, f54, f55, f56,
f57, f58, f59, f60, f61, f62, f63, f64);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
66, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
67, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
68, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
69, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
70, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
71, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
72, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
73, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
74, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
75, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
76, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
77, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
78, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
79, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
80, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
81, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
82, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
83, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
84, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
85, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
86, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
87, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
88, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
89, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
90, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
91, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
92, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
93, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
94, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
95, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
96, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
97, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
98, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
99, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97, f98);
RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER(
100, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45,
f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60,
f61, f62, f63, f64, f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75,
f76, f77, f78, f79, f80, f81, f82, f83, f84, f85, f86, f87, f88, f89, f90,
f91, f92, f93, f94, f95, f96, f97, f98, f99);
#undef RFL_INTERNAL_DEFINE_TUPLE_VIEW_HELPER
template <class T>
constexpr auto tuple_view(T& t) {
return tuple_view_helper<num_fields<T>>::tuple_view(t);
}
template <class T, typename F>
constexpr auto bind_to_tuple(T& _t, const F& _f) {
auto view = tuple_view(_t);
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return std::make_tuple(_f(std::get<Is>(view))...);
}
(std::make_index_sequence<std::tuple_size_v<decltype(view)>>());
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,36 @@
#ifndef RFL_INTERNAL_COPY_FLATTENED_TUPLE_TO_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_COPY_FLATTENED_TUPLE_TO_NAMED_TUPLE_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "../Field.hpp"
#include "lit_name.hpp"
#include "../make_named_tuple.hpp"
namespace rfl {
namespace internal {
template <class FieldNames, class... Fields>
auto copy_flattened_tuple_to_named_tuple(const auto& _flattened_tuple,
Fields&&... _fields) {
constexpr auto size =
std::tuple_size_v<std::remove_cvref_t<decltype(_flattened_tuple)>>;
constexpr auto i = sizeof...(_fields);
if constexpr (i == size) {
return make_named_tuple(std::move(_fields)...);
} else {
const auto name_literal = FieldNames::template name_of<i>();
auto new_field = rfl::make_field<
lit_name_v<std::remove_cvref_t<decltype(name_literal)>>>(
std::get<i>(_flattened_tuple));
return copy_flattened_tuple_to_named_tuple<FieldNames>(
_flattened_tuple, std::move(_fields)..., std::move(new_field));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,20 @@
#ifndef RFL_INTERNAL_COPY_FROM_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_COPY_FROM_NAMED_TUPLE_HPP_
#include "move_from_named_tuple.hpp"
namespace rfl {
namespace internal {
/// Creates a struct of type T from a named tuple.
/// All fields of the struct must be an rfl::Field.
template <class T, class NamedTupleType>
T copy_from_named_tuple(const NamedTupleType& _n) {
auto n = _n;
return move_from_named_tuple<T>(std::move(n));
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,20 @@
#ifndef RFL_COPY_FROM_TUPLE_HPP_
#define RFL_COPY_FROM_TUPLE_HPP_
#include "move_from_tuple.hpp"
namespace rfl {
namespace internal {
/// Creates a struct of type T from a tuple by copying the underlying
/// fields.
template <class T, class TupleType>
T copy_from_tuple(const TupleType& _t) {
auto t = _t;
return move_from_tuple<T, TupleType>(std::move(t));
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,18 @@
#ifndef RFL_INTERNAL_COPY_TO_FIELD_TUPLE_HPP_
#define RFL_INTERNAL_COPY_TO_FIELD_TUPLE_HPP_
#include "move_to_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
auto copy_to_field_tuple(const T& _t) {
auto t = _t;
return move_to_field_tuple(std::move(t));
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_DEFINELITERAL_HPP_
#define RFL_INTERNAL_DEFINELITERAL_HPP_
#include "../Literal.hpp"
namespace rfl {
namespace internal {
/// Allows you to combine several literals.
template <class... LiteralTypes>
struct define_literal;
/// General case
template <StringLiteral... _content1, StringLiteral... _content2, class... Tail>
struct define_literal<Literal<_content1...>, Literal<_content2...>, Tail...> {
using type = typename define_literal<Literal<_content1..., _content2...>,
Tail...>::type;
};
/// Special case - only a single literal is left
template <StringLiteral... _content>
struct define_literal<Literal<_content...>> {
using type = Literal<_content...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,46 @@
#ifndef RFL_INTERNAL_DEFINENAMEDTUPLE_HPP_
#define RFL_INTERNAL_DEFINENAMEDTUPLE_HPP_
#include "../NamedTuple.hpp"
namespace rfl {
namespace internal {
template <class... FieldTypes>
struct define_named_tuple;
/// Allows you to combine several named tuples and/or additional fields.
/// Recursive case - all types are fields.
template <class Head, class... Tail>
struct define_named_tuple<Head, Tail...> {
using type = typename define_named_tuple<NamedTuple<Head>, Tail...>::type;
};
/// Allows you to combine several named tuples and/or additional fields.
/// Recursive case - first type is NamedTuple, second type is field.
template <class Head, class... TupContent, class... Tail>
struct define_named_tuple<NamedTuple<TupContent...>, Head, Tail...> {
using type = typename define_named_tuple<NamedTuple<TupContent..., Head>,
Tail...>::type;
};
/// Allows you to combine several named tuples and/or additional fields.
/// Recursive case - first type is NamedTuple, second type is also NamedTuple.
template <class... TupContent, class... TupContent2, class... Tail>
struct define_named_tuple<NamedTuple<TupContent...>, NamedTuple<TupContent2...>,
Tail...> {
using type =
typename define_named_tuple<NamedTuple<TupContent..., TupContent2...>,
Tail...>::type;
};
/// Allows you to combine several named tuples and/or additional fields.
template <class... TupContent>
struct define_named_tuple<NamedTuple<TupContent...>> {
using type = NamedTuple<TupContent...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,57 @@
#ifndef RFL_INTERNAL_DEFINETAGGEDUNION_HPP_
#define RFL_INTERNAL_DEFINETAGGEDUNION_HPP_
#include "../TaggedUnion.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
/// Allows you to combine several tagged unions.
template <StringLiteral _discriminator, class... TaggedUnionTypes>
struct define_tagged_union;
/// Recursive case - both tagged union.
template <StringLiteral _discriminator, class... NamedTupleTypes1,
class... NamedTupleTypes2, class... Tail>
struct define_tagged_union<
_discriminator, TaggedUnion<_discriminator, NamedTupleTypes1...>,
TaggedUnion<_discriminator, NamedTupleTypes2...>, Tail...> {
using type = typename define_tagged_union<
_discriminator,
TaggedUnion<_discriminator, NamedTupleTypes1..., NamedTupleTypes2...>,
Tail...>::type;
};
/// Recursive case - tagged union plus named tuple.
template <StringLiteral _discriminator, class... NamedTupleTypes,
class... FieldTypes, class... Tail>
struct define_tagged_union<_discriminator,
TaggedUnion<_discriminator, NamedTupleTypes...>,
NamedTuple<FieldTypes...>, Tail...> {
using type = typename define_tagged_union<
_discriminator,
TaggedUnion<_discriminator, NamedTupleTypes...,
NamedTuple<FieldTypes...>>,
Tail...>::type;
};
/// Recursive case - named tuple.
template <StringLiteral _discriminator, class... FieldTypes, class... Tail>
struct define_tagged_union<_discriminator, NamedTuple<FieldTypes...>, Tail...> {
using type = typename define_tagged_union<
_discriminator, TaggedUnion<_discriminator, NamedTuple<FieldTypes...>>,
Tail...>::type;
};
/// Special case - only a single TaggedUnion is left.
template <StringLiteral _discriminator, class... NamedTupleTypes>
struct define_tagged_union<_discriminator,
TaggedUnion<_discriminator, NamedTupleTypes...>> {
using type = TaggedUnion<_discriminator, NamedTupleTypes...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,42 @@
#ifndef RFL_INTERNAL_DEFINEVARIANT_HPP_
#define RFL_INTERNAL_DEFINEVARIANT_HPP_
#include <variant>
namespace rfl {
namespace internal {
/// Allows you to combine several variants.
template <class... Vars>
struct define_variant;
/// Recursive case - both variants.
template <class... Vars1, class... Vars2, class... Tail>
struct define_variant<std::variant<Vars1...>, std::variant<Vars2...>, Tail...> {
using type = typename define_variant<std::variant<Vars1..., Vars2...>,
Tail...>::type;
};
/// Recursive case - variant plus other type.
template <class... Vars, class Head, class... Tail>
struct define_variant<std::variant<Vars...>, Head, Tail...> {
using type =
typename define_variant<std::variant<Vars..., Head>, Tail...>::type;
};
/// Recursive case - other type.
template <class Head, class... Tail>
struct define_variant<Head, Tail...> {
using type = typename define_variant<std::variant<Head>, Tail...>::type;
};
/// Special case - only a single variant is left.
template <class... Vars>
struct define_variant<std::variant<Vars...>> {
using type = std::variant<Vars...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,76 @@
#ifndef RFL_INTERNAL_ENUMS_NAMES_HPP_
#define RFL_INTERNAL_ENUMS_NAMES_HPP_
#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include "../../Literal.hpp"
#include "../../define_literal.hpp"
#include "../../make_named_tuple.hpp"
#include "../StringLiteral.hpp"
namespace rfl {
namespace internal {
namespace enums {
template <class EnumType, class LiteralType, size_t N, auto... _enums>
struct Names {
/// Contains a collection of enums as compile-time strings.
using Literal = LiteralType;
/// The number of possible values
constexpr static size_t size = N;
/// A list of all the possible enums
constexpr static std::array<EnumType, N> enums_ =
std::array<EnumType, N>{_enums...};
static_assert(N == 0 || LiteralType::size() == N,
"Size of literal and enum do not match.");
template <class NewLiteral, auto _new_enum>
using AddOneType = std::conditional_t<
N == 0, Names<EnumType, NewLiteral, 1, _new_enum>,
Names<EnumType, define_literal_t<LiteralType, NewLiteral>, N + 1,
_enums..., _new_enum>>;
};
template <class EnumType, size_t N, StringLiteral... _names, auto... _enums>
auto names_to_enumerator_named_tuple(
Names<EnumType, Literal<_names...>, N, _enums...>) {
return make_named_tuple(Field<_names, EnumType>{_enums}...);
}
template <class EnumType, size_t N, StringLiteral... _names, auto... _enums>
auto names_to_underlying_enumerator_named_tuple(
Names<EnumType, Literal<_names...>, N, _enums...>) {
return make_named_tuple(Field<_names, std::underlying_type_t<EnumType>>{
static_cast<std::underlying_type_t<EnumType>>(_enums)}...);
}
template <class EnumType, size_t N, StringLiteral... _names, auto... _enums>
constexpr std::array<std::pair<std::string_view, EnumType>, N>
names_to_enumerator_array(Names<EnumType, Literal<_names...>, N, _enums...>) {
return {
std::make_pair(LiteralHelper<_names>::field_.string_view(), _enums)...};
}
template <class EnumType, size_t N, StringLiteral... _names, auto... _enums>
constexpr std::array<
std::pair<std::string_view, std::underlying_type_t<EnumType>>, N>
names_to_underlying_enumerator_array(
Names<EnumType, Literal<_names...>, N, _enums...>) {
return {
std::make_pair(LiteralHelper<_names>::field_.string_view(),
static_cast<std::underlying_type_t<EnumType>>(_enums))...};
}
} // namespace enums
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,132 @@
#ifndef RFL_INTERNAL_ENUMS_STRINGCONVERTER_HPP_
#define RFL_INTERNAL_ENUMS_STRINGCONVERTER_HPP_
#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <type_traits>
#include "../../Result.hpp"
#include "../../internal/strings/join.hpp"
#include "../../internal/strings/split.hpp"
#include "../../type_name_t.hpp"
#include "get_enum_names.hpp"
#include "is_flag_enum.hpp"
namespace rfl {
namespace internal {
namespace enums {
template <class EnumType>
class StringConverter {
public:
static constexpr bool is_flag_enum_ = is_flag_enum<EnumType>;
static constexpr auto names_ = get_enum_names<EnumType, is_flag_enum_>();
using NamesLiteral = typename decltype(names_)::Literal;
public:
/// Transform an enum to a matching string.
static std::string enum_to_string(const EnumType _enum) {
if constexpr (is_flag_enum_) {
return flag_enum_to_string(_enum);
} else {
return enum_to_single_string(_enum);
}
}
/// Transforms a string to the matching enum.
static Result<EnumType> string_to_enum(const std::string& _str) {
static_assert(names_.size != 0,
"No enum could be identified. Please choose enum values "
"between 0 to 127 or for flag enums choose 1,2,4,8,16,...");
if constexpr (is_flag_enum_) {
return string_to_flag_enum(_str);
} else {
return single_string_to_enum(_str);
}
}
private:
/// Iterates through the enum bit by bit and matches it against the flags.
static std::string flag_enum_to_string(const EnumType _e) {
using T = std::underlying_type_t<EnumType>;
auto val = static_cast<T>(_e);
int i = 0;
std::vector<std::string> flags;
while (val != 0) {
const auto bit = val & static_cast<T>(1);
if (bit == 1) {
auto str = enum_to_single_string(
static_cast<EnumType>(static_cast<T>(1) << i));
flags.emplace_back(std::move(str));
}
++i;
val >>= 1;
}
return strings::join("|", flags);
}
/// This assumes that _enum can be exactly matched to one of the names and
/// does not have to be combined using |.
static std::string enum_to_single_string(const EnumType _enum) {
const auto to_str = [](const auto _l) { return _l.str(); };
for (size_t i = 0; i < names_.size; ++i) {
if (names_.enums_[i] == _enum) {
return NamesLiteral::from_value(
static_cast<typename NamesLiteral::ValueType>(i))
.transform(to_str)
.value();
}
}
return std::to_string(static_cast<std::underlying_type_t<EnumType>>(_enum));
}
/// Finds the enum matching the literal.
static EnumType literal_to_enum(const NamesLiteral _lit) noexcept {
return names_.enums_[_lit.value()];
}
/// This assumes that _enum can be exactly matched to one of the names and
/// does not have to be combined using |.
static Result<EnumType> single_string_to_enum(const std::string& _str) {
const auto r = NamesLiteral::from_string(_str).transform(literal_to_enum);
if (r) {
return r;
} else {
try {
return static_cast<EnumType>(std::stoi(_str));
} catch (std::exception& exp) {
return Error(exp.what());
}
}
}
/// Only relevant if this is a flag enum - combines the different matches
/// using |.
static Result<EnumType> string_to_flag_enum(
const std::string& _str) noexcept {
using T = std::underlying_type_t<EnumType>;
const auto split = strings::split(_str, "|");
auto res = static_cast<T>(0);
for (const auto& s : split) {
const auto r = single_string_to_enum(s);
if (r) {
res |= static_cast<T>(*r);
} else {
return r;
}
}
return static_cast<EnumType>(res);
}
};
} // namespace enums
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,151 @@
#ifndef RFL_INTERNAL_ENUMS_GET_ENUM_NAMES_HPP_
#define RFL_INTERNAL_ENUMS_GET_ENUM_NAMES_HPP_
#include <limits>
#include <source_location>
#include <type_traits>
#include "../../Literal.hpp"
#include "../../define_literal.hpp"
#include "../../internal/remove_namespaces.hpp"
#include "Names.hpp"
#include "is_scoped_enum.hpp"
// https://en.cppreference.com/w/cpp/language/static_cast:
// 8) A value of integer or enumeration type can be converted to any complete
// enumeration type.
// If the underlying type is not fixed, the behavior is undefined if the value
// of expression is out of range (the range is all values possible for the
// smallest bit-field large enough to hold all enumerators of the target
// enumeration). If the underlying type is fixed, the result is the same as
// converting the original value first to the underlying type of the enumeration
// and then to the enumeration type.
// https://en.cppreference.com/w/cpp/language/enum
// enum struct|class name { enumerator = constexpr , enumerator = constexpr ,
// ... } (1)
// ...
// 1) declares a scoped enumeration type whose underlying type is int (the
// keywords class and struct are exactly equivalent)
//
// --> These rules taken together imply that if you EITHER fix the type OR you
// use a scoped integer, static_cast<MyEnum>(some_integer_value) will always be
// defined.
namespace rfl {
namespace internal {
namespace enums {
template <auto e>
consteval auto get_enum_name_str_view() {
// Unfortunately, we cannot avoid the use of a compiler-specific macro for
// Clang on Windows. For all other compilers, function_name works as intended.
#if defined(__clang__) && defined(_MSC_VER)
const auto func_name = std::string_view{__PRETTY_FUNCTION__};
#else
const auto func_name =
std::string_view{std::source_location::current().function_name()};
#endif
#if defined(__clang__)
const auto split = func_name.substr(0, func_name.size() - 1);
return split.substr(split.find("e = ") + 4);
#elif defined(__GNUC__)
const auto split = func_name.substr(0, func_name.size() - 1);
return split.substr(split.find("e = ") + 4);
#elif defined(_MSC_VER)
const auto split = func_name.substr(0, func_name.size() - 7);
return split.substr(split.find("get_enum_name_str_view<") + 23);
#else
static_assert(false,
"You are using an unsupported compiler. Please use GCC, Clang "
"or MSVC or use rfl::Literal.");
#endif
}
template <auto e>
consteval auto get_enum_name() {
constexpr auto name = get_enum_name_str_view<e>();
const auto to_str_lit = [&]<auto... Ns>(std::index_sequence<Ns...>) {
return StringLiteral<sizeof...(Ns) + 1>{name[Ns]...};
};
return to_str_lit(std::make_index_sequence<name.size()>{});
}
template <class T>
consteval T calc_greatest_power_of_two() {
if constexpr (std::is_signed_v<T>) {
return static_cast<T>(1) << (sizeof(T) * 8 - 2);
} else {
return static_cast<T>(1) << (sizeof(T) * 8 - 1);
}
}
template <class T, bool _is_flag>
consteval T get_max() {
if constexpr (_is_flag) {
return calc_greatest_power_of_two<T>();
} else {
return std::numeric_limits<T>::max() > 127 ? static_cast<T>(127)
: std::numeric_limits<T>::max();
}
}
template <class T, bool _is_flag, int _i>
consteval T calc_j() {
if constexpr (_is_flag) {
return static_cast<T>(1) << _i;
} else {
return static_cast<T>(_i);
}
}
template <class EnumType, class NamesType, auto _max, bool _is_flag, int _i>
consteval auto get_enum_names_impl() {
using T = std::underlying_type_t<EnumType>;
constexpr T j = calc_j<T, _is_flag, _i>();
constexpr auto name = get_enum_name<static_cast<EnumType>(j)>();
if constexpr (std::get<0>(name.arr_) == '(') {
if constexpr (j == _max) {
return NamesType{};
} else {
return get_enum_names_impl<EnumType, NamesType, _max, _is_flag, _i + 1>();
}
} else {
using NewNames = typename NamesType::template AddOneType<
Literal<remove_namespaces<name>()>, static_cast<EnumType>(j)>;
if constexpr (j == _max) {
return NewNames{};
} else {
return get_enum_names_impl<EnumType, NewNames, _max, _is_flag, _i + 1>();
}
}
}
template <class EnumType, bool _is_flag>
consteval auto get_enum_names() {
static_assert(is_scoped_enum<EnumType>,
"You must use scoped enums (using class or struct) for the "
"parsing to work!");
static_assert(std::is_integral_v<std::underlying_type_t<EnumType>>,
"The underlying type of any Enum must be integral!");
constexpr auto max = get_max<std::underlying_type_t<EnumType>, _is_flag>();
using EmptyNames = Names<EnumType, rfl::Literal<"">, 0>;
return get_enum_names_impl<EnumType, EmptyNames, max, _is_flag, 0>();
}
} // namespace enums
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,22 @@
#ifndef RFL_INTERNAL_ENUMS_IS_FLAG_ENUM_HPP_
#define RFL_INTERNAL_ENUMS_IS_FLAG_ENUM_HPP_
#include <concepts>
#include "is_scoped_enum.hpp"
namespace rfl {
namespace internal {
namespace enums {
template <class EnumType>
concept is_flag_enum = is_scoped_enum<EnumType> &&
requires(EnumType e1, EnumType e2) {
{ e1 | e2 } -> std::same_as<EnumType>;
};
} // namespace enums
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,19 @@
#ifndef RFL_INTERNAL_ENUMS_IS_SCOPED_ENUM_HPP_
#define RFL_INTERNAL_ENUMS_IS_SCOPED_ENUM_HPP_
#include <concepts>
#include <type_traits>
namespace rfl {
namespace internal {
namespace enums {
template <class EnumType>
concept is_scoped_enum = std::is_enum_v<EnumType> &&
!std::is_convertible_v<EnumType, std::underlying_type_t<EnumType>>;
} // namespace enums
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,25 @@
#ifndef RFL_INTERNAL_EXTRACTDISTRIMINATORS_HPP_
#define RFL_INTERNAL_EXTRACTDISTRIMINATORS_HPP_
#include <type_traits>
#include "../TaggedUnion.hpp"
#include "../define_literal.hpp"
#include "../field_type.hpp"
namespace rfl {
namespace internal {
template <class TaggedUnionType>
struct extract_discriminators;
template <StringLiteral _discriminator, class... NamedTupleType>
struct extract_discriminators<TaggedUnion<_discriminator, NamedTupleType...>> {
using type = define_literal_t<
std::remove_cvref_t<field_type_t<_discriminator, NamedTupleType>>...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,20 @@
#ifndef RFL_INTERNAL_FIELD_TUPLE_T_HPP_
#define RFL_INTERNAL_FIELD_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "copy_to_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using field_tuple_t =
typename std::invoke_result<decltype(copy_to_field_tuple<T>), T>::type;
}
} // namespace rfl
#endif

View file

@ -0,0 +1,63 @@
#ifndef RFL_INTERNAL_FIELD_TYPE_HPP_
#define RFL_INTERNAL_FIELD_TYPE_HPP_
#include <tuple>
#include <type_traits>
#include <variant>
#include "../NamedTuple.hpp"
#include "../TaggedUnion.hpp"
#include "StringLiteral.hpp"
#include "find_index.hpp"
#include "../named_tuple_t.hpp"
namespace rfl {
namespace internal {
template <class T, class... Ts>
struct are_same : std::conjunction<std::is_same<T, Ts>...> {};
/// Finds the type of the field signified by _field_name
template <StringLiteral _field_name, class T>
struct FieldType;
/// Default option - for named tuples.
template <StringLiteral _field_name, class T>
struct FieldType {
using NamedTupleType = named_tuple_t<T>;
static constexpr int field_ix_ =
internal::find_index<_field_name, typename NamedTupleType::Fields>();
using Type = typename std::tuple_element<
field_ix_, typename NamedTupleType::Fields>::type::Type;
};
/// For variants - in this case the FieldType returned by all options must be
/// the same.
template <StringLiteral _field_name, class FirstAlternativeType,
class... OtherAlternativeTypes>
struct FieldType<_field_name,
std::variant<FirstAlternativeType, OtherAlternativeTypes...>> {
constexpr static bool all_types_match = std::conjunction_v<std::is_same<
typename FieldType<_field_name, FirstAlternativeType>::Type,
typename FieldType<_field_name, OtherAlternativeTypes>::Type>...>;
static_assert(all_types_match, "All field types must be the same.");
using Type = typename FieldType<_field_name, FirstAlternativeType>::Type;
};
/// For tagged union - just defers to the variant.
template <StringLiteral _field_name, StringLiteral _discriminator_name,
class... VarTypes>
struct FieldType<_field_name, TaggedUnion<_discriminator_name, VarTypes...>> {
using Type = typename FieldType<
_field_name, typename TaggedUnion<_discriminator_name,
VarTypes...>::VariantType>::Type;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,39 @@
#ifndef RFL_FIND_INDEX_HPP_
#define RFL_FIND_INDEX_HPP_
#include <tuple>
#include <type_traits>
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
/// Finds the index of the field signified by _field_name
template <StringLiteral _field_name, class Fields, int I = 0>
constexpr static int find_index() {
using FieldType =
std::remove_cvref_t<typename std::tuple_element<I, Fields>::type>;
constexpr bool name_i_matches = (FieldType::name_ == _field_name);
if constexpr (name_i_matches) {
return I;
} else {
constexpr bool out_of_range = I + 1 == std::tuple_size_v<Fields>;
static_assert(!out_of_range, "Field name not found!");
if constexpr (out_of_range) {
// This is to avoid very confusing error messages.
return I;
} else {
return find_index<_field_name, Fields, I + 1>();
}
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,19 @@
#ifndef RFL_INTERNAL_FLATTENED_PTR_TUPLE_T_HPP_
#define RFL_INTERNAL_FLATTENED_PTR_TUPLE_T_HPP_
#include <functional>
#include <type_traits>
#include "to_flattened_ptr_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using flattened_ptr_tuple_t =
typename std::invoke_result<decltype(to_flattened_ptr_tuple<T>), T>::type;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,22 @@
#ifndef RFL_INTERNAL_FLATTENED_TUPLE_T_HPP_
#define RFL_INTERNAL_FLATTENED_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "flattened_ptr_tuple_t.hpp"
#include "remove_ptrs_tup.hpp"
#include "../to_named_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using flattened_tuple_t =
typename remove_ptrs_tup<flattened_ptr_tuple_t<T>>::TupleType;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,46 @@
#ifndef RFL_INTERNAL_GETFAKEOBJECT_HPP_
#define RFL_INTERNAL_GETFAKEOBJECT_HPP_
namespace rfl {
namespace internal {
#if __GNUC__
#ifndef __clang__
#pragma GCC system_header
#endif
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"
#pragma clang diagnostic ignored "-Wundefined-internal"
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 7631)
#endif
template <class T>
struct wrapper {
const T value;
static const wrapper<T> report_if_you_see_a_link_error_with_this_object;
};
template <class T>
consteval const T& get_fake_object() noexcept {
return wrapper<T>::report_if_you_see_a_link_error_with_this_object.value;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,156 @@
#ifndef RFL_INTERNAL_GETFIELDNAMES_HPP_
#define RFL_INTERNAL_GETFIELDNAMES_HPP_
#include <array>
#include <iostream>
#include <memory>
#include <source_location>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Literal.hpp"
#include "bind_fake_object_to_tuple.hpp"
#include "get_fake_object.hpp"
#include "is_flatten_field.hpp"
#include "is_rename.hpp"
#include "num_fields.hpp"
#if __GNUC__
#ifndef __clang__
#pragma GCC system_header
#endif
#endif
namespace rfl::internal {
template <class T>
struct Wrapper {
using Type = T;
T v;
};
template <class T>
Wrapper(T) -> Wrapper<T>;
// This workaround is necessary for clang.
template <class T>
constexpr auto wrap(const T& arg) noexcept {
return Wrapper{arg};
}
template <class T, auto ptr>
consteval auto get_field_name_str_view() {
// Unfortunately, we cannot avoid the use of a compiler-specific macro for
// Clang on Windows. For all other compilers, function_name works as intended.
#if defined(__clang__) && defined(_MSC_VER)
const auto func_name = std::string_view{__PRETTY_FUNCTION__};
#else
const auto func_name =
std::string_view{std::source_location::current().function_name()};
#endif
#if defined(__clang__)
const auto split = func_name.substr(0, func_name.size() - 2);
return split.substr(split.find_last_of(":.") + 1);
#elif defined(__GNUC__)
const auto split = func_name.substr(0, func_name.size() - 2);
return split.substr(split.find_last_of(":") + 1);
#elif defined(_MSC_VER)
const auto split = func_name.substr(0, func_name.size() - 7);
return split.substr(split.rfind("->") + 2);
#else
static_assert(false,
"You are using an unsupported compiler. Please use GCC, Clang "
"or MSVC or switch to the rfl::Field-syntax.");
#endif
}
template <class T, auto ptr>
consteval auto get_field_name_str_lit() {
constexpr auto name = get_field_name_str_view<T, ptr>();
const auto to_str_lit = [&]<auto... Ns>(std::index_sequence<Ns...>) {
return StringLiteral<sizeof...(Ns) + 1>{name[Ns]...};
};
return to_str_lit(std::make_index_sequence<name.size()>{});
}
template <class T>
auto get_field_names();
template <class T, auto ptr>
auto get_field_name() {
#if defined(__clang__)
using Type = std::remove_cvref_t<std::remove_pointer_t<
typename std::remove_pointer_t<decltype(ptr)>::Type>>;
#else
using Type = std::remove_cvref_t<std::remove_pointer_t<decltype(ptr)>>;
#endif
if constexpr (is_rename_v<Type>) {
using Name = typename Type::Name;
return Name();
} else if constexpr (is_flatten_field_v<Type>) {
return get_field_names<std::remove_cvref_t<typename Type::Type>>();
} else {
return rfl::Literal<get_field_name_str_lit<T, ptr>()>();
}
}
template <StringLiteral... _names1, StringLiteral... _names2>
auto concat_two_literals(const rfl::Literal<_names1...>& _lit1,
const rfl::Literal<_names2...>& _lit2) {
return rfl::Literal<_names1..., _names2...>::template from_value<0>();
}
template <class Head, class... Tail>
auto concat_literals(const Head& _head, const Tail&... _tail) {
if constexpr (sizeof...(_tail) == 0) {
return _head;
} else {
return concat_two_literals(_head, concat_literals(_tail...));
}
}
inline auto concat_literals() { return rfl::Literal<>(); }
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"
#pragma clang diagnostic ignored "-Wundefined-inline"
#endif
template <class T>
#if __GNUC__
#ifndef __clang__
[[gnu::no_sanitize_undefined]]
#endif
#endif
auto get_field_names() {
using Type = std::remove_cvref_t<T>;
if constexpr (std::is_pointer_v<Type>) {
return get_field_names<std::remove_pointer_t<T>>();
} else {
#if defined(__clang__)
const auto get = []<std::size_t... Is>(std::index_sequence<Is...>) {
return concat_literals(
get_field_name<Type, wrap(std::get<Is>(
bind_fake_object_to_tuple<T>()))>()...);
};
#else
const auto get = []<std::size_t... Is>(std::index_sequence<Is...>) {
return concat_literals(
get_field_name<Type,
std::get<Is>(bind_fake_object_to_tuple<T>())>()...);
};
#endif
return get(std::make_index_sequence<num_fields<T>>());
}
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,32 @@
#ifndef RFL_INTERNAL_GETMETAFIELDS_HPP_
#define RFL_INTERNAL_GETMETAFIELDS_HPP_
#include <array>
#include <tuple>
#include <utility>
#include "../MetaField.hpp"
#include "../type_name_t.hpp"
namespace rfl {
namespace internal {
template <class NamedTupleType, class... AlreadyExtracted>
auto get_meta_fields(AlreadyExtracted&&... _already_extracted) {
constexpr size_t i = sizeof...(_already_extracted);
if constexpr (NamedTupleType::size() == i) {
return std::array<MetaField, i>{std::move(_already_extracted)...};
} else {
using FieldType = std::tuple_element_t<i, typename NamedTupleType::Fields>;
auto name = typename FieldType::Name().str();
auto type = type_name_t<typename FieldType::Type>().str();
return get_meta_fields<NamedTupleType>(
std::move(_already_extracted)...,
MetaField(std::move(name), std::move(type)));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,57 @@
#ifndef RFL_INTERNAL_GETTYPENAME_HPP_
#define RFL_INTERNAL_GETTYPENAME_HPP_
#include <source_location>
#include <string>
#include <utility>
namespace rfl {
namespace internal {
template <class T>
consteval auto get_type_name_str_view() {
// Unfortunately, we cannot avoid the use of a compiler-specific macro for
// Clang on Windows. For all other compilers, function_name works as intended.
#if defined(__clang__) && defined(_MSC_VER)
const auto func_name = std::string_view{__PRETTY_FUNCTION__};
#else
const auto func_name =
std::string_view{std::source_location::current().function_name()};
#endif
#if defined(__clang__)
const auto split = func_name.substr(0, func_name.size() - 1);
return split.substr(split.find("T = ") + 4);
#elif defined(__GNUC__)
const auto split = func_name.substr(0, func_name.size() - 1);
return split.substr(split.find("T = ") + 4);
#elif defined(_MSC_VER)
auto split = func_name.substr(0, func_name.size() - 7);
split = split.substr(split.find("get_type_name_str_view<") + 23);
auto pos = split.find(" ");
if (pos != std::string_view::npos) {
return split.substr(pos + 1);
}
return split;
#else
static_assert(
false,
"You are using an unsupported compiler. Please use GCC, Clang "
"or MSVC or explicitly tag your structs using 'Tag' or 'Name'.");
#endif
}
template <class T>
consteval auto get_type_name() {
static_assert(get_type_name_str_view<int>() == "int",
"Expected 'int', got something else.");
constexpr auto name = get_type_name_str_view<T>();
const auto to_str_lit = [&]<auto... Ns>(std::index_sequence<Ns...>) {
return StringLiteral<sizeof...(Ns) + 1>{name[Ns]...};
};
return to_str_lit(std::make_index_sequence<name.size()>{});
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,71 @@
#ifndef RFL_INTERNAL_HASFIELDS_HPP_
#define RFL_INTERNAL_HASFIELDS_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "all_fields.hpp"
#include "is_field.hpp"
#include "is_flatten_field.hpp"
#include "ptr_tuple_t.hpp"
namespace rfl {
namespace internal {
template <class TupleType, int _i = 0>
constexpr bool all_fields_or_flatten() {
if constexpr (_i == std::tuple_size_v<TupleType>) {
return true;
} else {
using T = std::remove_cvref_t<std::tuple_element_t<_i, TupleType>>;
if constexpr (is_flatten_field_v<T>) {
return all_fields_or_flatten<
ptr_tuple_t<typename std::remove_pointer_t<T>::Type>>() &&
all_fields_or_flatten<TupleType, _i + 1>();
} else {
return is_field_v<T> && all_fields_or_flatten<TupleType, _i + 1>();
}
}
}
template <class TupleType, int _i = 0>
constexpr bool some_fields_or_flatten() {
if constexpr (_i == std::tuple_size_v<TupleType>) {
return false;
} else {
using T = std::remove_cvref_t<std::tuple_element_t<_i, TupleType>>;
if constexpr (is_flatten_field_v<T>) {
return some_fields_or_flatten<
ptr_tuple_t<typename std::remove_pointer_t<T>::Type>>() ||
some_fields_or_flatten<TupleType, _i + 1>();
} else {
return is_field_v<T> || some_fields_or_flatten<TupleType, _i + 1>();
}
}
}
template <class T>
constexpr bool has_fields() {
if constexpr (is_named_tuple_v<T>) {
return true;
} else {
using TupleType = ptr_tuple_t<T>;
if constexpr (some_fields_or_flatten<TupleType>()) {
static_assert(
all_fields_or_flatten<TupleType>(),
"If some of your fields are annotated using rfl::Field<...>, "
"then you must annotate all of your fields. "
"Also, you cannot combine annotated and "
"unannotated fields using rfl::Flatten<...>.");
return true;
} else {
return false;
}
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,26 @@
#ifndef RFL_INTERNAL_HASFLATTENFIELDS_HPP_
#define RFL_INTERNAL_HASFLATTENFIELDS_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "is_flatten_field.hpp"
namespace rfl {
namespace internal {
template <class TupleType, int _i = 0>
constexpr bool has_flatten_fields() {
if constexpr (_i == std::tuple_size_v<TupleType>) {
return false;
} else {
using T = std::remove_cvref_t<std::tuple_element_t<_i, TupleType>>;
return is_flatten_field_v<T> || has_flatten_fields<TupleType, _i + 1>();
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_HASREFLECTIONMETHODV_HPP_
#define RFL_INTERNAL_HASREFLECTIONMETHODV_HPP_
#include <type_traits>
namespace rfl {
namespace internal {
template <typename Wrapper>
using reflection_method_t =
decltype(std::declval<const Wrapper>().reflection());
template <typename Wrapper, typename = std::void_t<>>
struct has_refl_m : std::false_type {};
template <typename Wrapper>
struct has_refl_m<Wrapper, std::void_t<reflection_method_t<Wrapper>>>
: std::true_type {};
/// Utility parameter for named tuple parsing, can be used by the
/// parsers to determine whether a class or struct has a method
/// called "reflection".
template <typename Wrapper>
constexpr bool has_reflection_method_v = has_refl_m<Wrapper>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,33 @@
#ifndef RFL_HASREFLECTIONTYPEV_HPP_
#define RFL_HASREFLECTIONTYPEV_HPP_
#include <cstdint>
#include <utility>
namespace rfl {
namespace internal {
template <class Wrapper>
class HasReflectionType {
private:
template <class U>
static std::int64_t foo(...);
template <class U>
static std::int32_t foo(typename U::ReflectionType*);
public:
static constexpr bool value =
sizeof(foo<Wrapper>(nullptr)) == sizeof(std::int32_t);
};
/// Utility parameter for named tuple parsing, can be used by the
/// parsers to determine whether a class or struct defines a type
/// called "ReflectionType".
template <typename Wrapper>
constexpr bool has_reflection_type_v = HasReflectionType<Wrapper>::value;
} // namespace internal
} // namespace rfl
#endif // RFL_HASNAMEDTUPLETYPEV_HPP_

View file

@ -0,0 +1,31 @@
#ifndef RFL_HASTAGV_HPP_
#define RFL_HASTAGV_HPP_
#include <cstdint>
#include <utility>
namespace rfl {
namespace internal {
template <class Wrapper>
class HasTag {
private:
template <class U>
static std::int64_t foo(...);
template <class U>
static std::int32_t foo(typename U::Tag*);
public:
static constexpr bool value =
sizeof(foo<Wrapper>(nullptr)) == sizeof(std::int32_t);
};
/// Used for tagged unions - determines whether a struct as a Tag.
template <typename Wrapper>
constexpr bool has_tag_v = HasTag<Wrapper>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_HASTOCLASSMETHODV_HPP_
#define RFL_INTERNAL_HASTOCLASSMETHODV_HPP_
#include <type_traits>
namespace rfl {
namespace internal {
template <typename Wrapper>
using to_class_method_t = decltype(std::declval<const Wrapper>().to_class());
template <typename Wrapper, typename = std::void_t<>>
struct has_to_class_m : std::false_type {};
template <typename Wrapper>
struct has_to_class_m<Wrapper, std::void_t<to_class_method_t<Wrapper>>>
: std::true_type {};
/// Utility parameter for named tuple parsing, can be used by the
/// parsers to determine whether a class or struct has a method
/// called "to_class".
template <typename Wrapper>
constexpr bool has_to_class_method_v = has_to_class_m<Wrapper>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,27 @@
#ifndef RFL_INTERNAL_ISARRAY_HPP_
#define RFL_INTERNAL_ISARRAY_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "Array.hpp"
namespace rfl::internal {
template <class T>
class is_array;
template <class T>
class is_array : public std::false_type {};
template <class Type>
class is_array<Array<Type>> : public std::true_type {};
template <class T>
constexpr bool is_array_v =
is_array<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,31 @@
#ifndef RFL_INTERNAL_ISATTRIBUTE_HPP_
#define RFL_INTERNAL_ISATTRIBUTE_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Attribute.hpp"
#include "../Field.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_attribute;
template <class T>
class is_attribute : public std::false_type {};
template <class Type>
class is_attribute<Attribute<Type>> : public std::true_type {};
template <class T>
constexpr bool is_attribute_v =
is_attribute<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,20 @@
#ifndef RFL_INTERNAL_ISBASICTYPE_HPP_
#define RFL_INTERNAL_ISBASICTYPE_HPP_
#include <string>
#include <type_traits>
namespace rfl {
namespace internal {
template <class T>
constexpr bool is_basic_type_v =
std::is_floating_point_v<std::remove_cvref_t<T>> ||
std::is_integral_v<std::remove_cvref_t<T>> ||
std::is_same<std::remove_cvref_t<T>, std::string>() ||
std::is_same<std::remove_cvref_t<T>, bool>();
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,30 @@
#ifndef RFL_INTERNAL_ISDESCRIPTION_HPP_
#define RFL_INTERNAL_ISDESCRIPTION_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Description.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_description;
template <class T>
class is_description : public std::false_type {};
template <StringLiteral _name, class Type>
class is_description<Description<_name, Type>> : public std::true_type {};
template <class T>
constexpr bool is_description_v =
is_description<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,24 @@
#ifndef RFL_INTERNAL_ISEMPTY_HPP_
#define RFL_INTERNAL_ISEMPTY_HPP_
#include <tuple>
#include <type_traits>
#include "is_named_tuple.hpp"
namespace rfl::internal {
template <class T>
constexpr bool is_empty() {
using U = std::remove_cvref_t<std::remove_pointer_t<T>>;
if constexpr (is_named_tuple_v<U>) {
return U::size() == 0;
} else {
using TupleType = ptr_tuple_t<U>;
return std::tuple_size_v<TupleType> == 0;
}
}
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,30 @@
#ifndef RFL_INTERNAL_ISFIELD_HPP_
#define RFL_INTERNAL_ISFIELD_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Field.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_field;
template <class T>
class is_field : public std::false_type {};
template <StringLiteral _name, class Type>
class is_field<Field<_name, Type>> : public std::true_type {};
template <class T>
constexpr bool is_field_v =
is_field<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_ISFLATTENFIELD_HPP_
#define RFL_INTERNAL_ISFLATTENFIELD_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Flatten.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_flatten_field;
template <class T>
class is_flatten_field : public std::false_type {};
template <class T>
class is_flatten_field<Flatten<T>> : public std::true_type {};
template <class T>
constexpr bool is_flatten_field_v =
is_flatten_field<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_ISLITERAL_HPP_
#define RFL_INTERNAL_ISLITERAL_HPP_
#include <type_traits>
#include "../Literal.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_literal;
template <class T>
class is_literal : public std::false_type {};
template <StringLiteral... _s>
class is_literal<Literal<_s...>> : public std::true_type {};
template <class T>
constexpr bool is_literal_v =
is_literal<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,27 @@
#ifndef RFL_INTERNAL_IS_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_IS_NAMED_TUPLE_HPP_
#include <type_traits>
#include "../NamedTuple.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_named_tuple;
template <class T>
class is_named_tuple : public std::false_type {};
template <class... Fields>
class is_named_tuple<NamedTuple<Fields...>> : public std::true_type {};
template <class T>
constexpr bool is_named_tuple_v =
is_named_tuple<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_ISNOOPTIONALS_HPP_
#define RFL_INTERNAL_ISNOOPTIONALS_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../NoOptionals.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_no_optionals;
template <class T>
class is_no_optionals : public std::false_type {};
template <>
class is_no_optionals<NoOptionals> : public std::true_type {};
template <class T>
constexpr bool is_no_optionals_v =
is_no_optionals<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_ISPATTERN_HPP_
#define RFL_INTERNAL_ISPATTERN_HPP_
#include <type_traits>
#include "../Pattern.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_pattern;
template <class T>
class is_pattern : public std::false_type {};
template <StringLiteral _regex, internal::StringLiteral _name>
class is_pattern<Pattern<_regex, _name>> : public std::true_type {};
template <class T>
constexpr bool is_pattern_v =
is_pattern<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,30 @@
#ifndef RFL_INTERNAL_ISRENAME_HPP_
#define RFL_INTERNAL_ISRENAME_HPP_
#include <tuple>
#include <type_traits>
#include <utility>
#include "../Rename.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_rename;
template <class T>
class is_rename : public std::false_type {};
template <StringLiteral _name, class Type>
class is_rename<Rename<_name, Type>> : public std::true_type {};
template <class T>
constexpr bool is_rename_v =
is_rename<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,26 @@
#ifndef RFL_INTERNAL_ISSKIP_HPP_
#define RFL_INTERNAL_ISSKIP_HPP_
#include <type_traits>
#include "Skip.hpp"
namespace rfl::internal {
template <class T>
class is_skip;
template <class T>
class is_skip : public std::false_type {};
template <class T, bool _skip_serialization, bool _skip_deserialization>
class is_skip<Skip<T, _skip_serialization, _skip_deserialization>>
: public std::true_type {};
template <class T>
constexpr bool is_skip_v =
is_skip<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_ISVALIDATOR_HPP_
#define RFL_INTERNAL_ISVALIDATOR_HPP_
#include <type_traits>
#include "../Validator.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <class T>
class is_validator;
template <class T>
class is_validator : public std::false_type {};
template <class T, class V, class... Vs>
class is_validator<Validator<T, V, Vs...>> : public std::true_type {};
template <class T>
constexpr bool is_validator_v =
is_validator<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,26 @@
#ifndef RFL_INTERNAL_ISVARIANT_HPP_
#define RFL_INTERNAL_ISVARIANT_HPP_
#include <type_traits>
#include <variant>
namespace rfl {
namespace internal {
template <class T>
class is_variant;
template <class T>
class is_variant : public std::false_type {};
template <class... T>
class is_variant<std::variant<T...>> : public std::true_type {};
template <class T>
constexpr bool is_variant_v =
is_variant<std::remove_cvref_t<std::remove_pointer_t<T>>>::value;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,23 @@
#ifndef RFL_INTERNAL_LIT_NAME_HPP_
#define RFL_INTERNAL_LIT_NAME_HPP_
#include "../Literal.hpp"
namespace rfl {
namespace internal {
template <class T>
struct lit_name;
template <auto _name>
struct lit_name<rfl::Literal<_name>> {
constexpr static auto name_ = _name;
};
template <class LiteralType>
constexpr auto lit_name_v = lit_name<LiteralType>::name_;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,34 @@
#ifndef RFL_INTERNAL_MAKE_TAG_HPP_
#define RFL_INTERNAL_MAKE_TAG_HPP_
#include "../Literal.hpp"
#include "../field_names_t.hpp"
#include "../named_tuple_t.hpp"
#include "../to_view.hpp"
#include "StringLiteral.hpp"
#include "get_type_name.hpp"
#include "has_reflection_type_v.hpp"
#include "has_tag_v.hpp"
#include "remove_namespaces.hpp"
namespace rfl::internal {
template <internal::StringLiteral _discriminator, class T>
static inline auto make_tag(const T& _t) noexcept {
if constexpr (internal::has_reflection_type_v<T>) {
return make_tag<typename T::ReflectionType>();
} else if constexpr (named_tuple_t<T>::Names::template contains<
_discriminator>()) {
return *to_view(_t).template get<_discriminator>();
} else if constexpr (internal::has_tag_v<T>) {
using LiteralType = typename T::Tag;
return LiteralType::template name_of<0>();
} else {
return rfl::Literal<
internal::remove_namespaces<internal::get_type_name<T>()>()>();
}
}
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,35 @@
#ifndef RFL_INTERNAL_MOVE_AND_FLATTEN_FIELD_TUPLE_HPP_
#define RFL_INTERNAL_MOVE_AND_FLATTEN_FIELD_TUPLE_HPP_
#include <tuple>
#include "is_flatten_field.hpp"
#include "move_to_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class FieldTuple, class... Args>
auto move_and_flatten_field_tuple(FieldTuple&& _t, Args&&... _args) {
constexpr auto i = sizeof...(Args);
if constexpr (i == std::tuple_size_v<std::remove_cvref_t<FieldTuple>>) {
return std::tuple_cat(std::move(_args)...);
} else {
using T = std::tuple_element_t<i, std::remove_cvref_t<FieldTuple>>;
if constexpr (is_flatten_field<T>::value) {
return move_and_flatten_field_tuple(
std::move(_t), std::move(_args)...,
move_and_flatten_field_tuple(
move_to_field_tuple(std::move(std::get<i>(_t).value_))));
} else {
return move_and_flatten_field_tuple(
std::move(_t), std::move(_args)...,
std::make_tuple(std::move(std::get<i>(_t))));
}
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,32 @@
#ifndef RFL_INTERNAL_MOVE_FIELD_TUPLE_TO_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_MOVE_FIELD_TUPLE_TO_NAMED_TUPLE_HPP_
#include <tuple>
#include <type_traits>
#include "../Field.hpp"
#include "has_flatten_fields.hpp"
#include "move_and_flatten_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class FieldTuple>
auto move_field_tuple_to_named_tuple(FieldTuple&& _field_tuple) {
const auto ft_to_nt = []<class... Fields>(Fields&&... _fields) {
return make_named_tuple(std::move(_fields)...);
};
if constexpr (!has_flatten_fields<std::remove_cvref_t<FieldTuple>>()) {
return std::apply(ft_to_nt, std::move(_field_tuple));
} else {
auto flattened_tuple =
move_and_flatten_field_tuple(std::move(_field_tuple));
return std::apply(ft_to_nt, std::move(flattened_tuple));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,105 @@
#ifndef RFL_MOVE_FROM_NAMED_TUPLE_HPP_
#define RFL_MOVE_FROM_NAMED_TUPLE_HPP_
#include <functional>
#include <type_traits>
#include "is_field.hpp"
#include "is_named_tuple.hpp"
#include "nt_to_ptr_named_tuple.hpp"
#include "ptr_field_tuple_t.hpp"
#include "../named_tuple_t.hpp"
namespace rfl {
namespace internal {
template <class PtrFieldTupleType, class PtrNamedTupleType, class... Args>
auto make_ptr_fields(PtrNamedTupleType& _n, Args... _args) {
constexpr auto i = sizeof...(Args);
constexpr auto size =
std::tuple_size_v<std::remove_cvref_t<PtrFieldTupleType>>;
if constexpr (i == size) {
return std::make_tuple(_args...);
} else {
using Field =
std::remove_cvref_t<std::tuple_element_t<i, PtrFieldTupleType>>;
using T = std::remove_cvref_t<std::remove_pointer_t<typename Field::Type>>;
if constexpr (is_named_tuple_v<T>) {
using SubPtrNamedTupleType =
typename std::invoke_result<decltype(nt_to_ptr_named_tuple<T>),
T>::type;
return make_ptr_fields<PtrFieldTupleType>(
_n, _args..., SubPtrNamedTupleType(_n).fields());
} else if constexpr (is_flatten_field<Field>::value) {
using SubPtrFieldTupleType = std::remove_cvref_t<ptr_field_tuple_t<T>>;
return make_ptr_fields<PtrFieldTupleType>(
_n, _args..., make_ptr_fields<SubPtrFieldTupleType>(_n));
} else {
return make_ptr_fields<PtrFieldTupleType>(
_n, _args..., _n.template get_field<Field::name_>());
}
}
}
template <class T, class Pointers, class... Args>
auto move_from_ptr_fields(Pointers& _ptrs, Args&&... _args) {
constexpr auto i = sizeof...(Args);
if constexpr (i == std::tuple_size_v<std::remove_cvref_t<Pointers>>) {
return T{std::move(_args)...};
} else {
using FieldType = std::tuple_element_t<i, std::remove_cvref_t<Pointers>>;
if constexpr (is_field_v<FieldType>) {
return move_from_ptr_fields<T>(
_ptrs, std::move(_args)...,
rfl::make_field<FieldType::name_>(
std::move(*std::get<i>(_ptrs).value())));
} else {
using PtrFieldTupleType = std::remove_cvref_t<ptr_field_tuple_t<T>>;
using U = std::remove_cvref_t<std::remove_pointer_t<
typename std::tuple_element_t<i, PtrFieldTupleType>::Type>>;
return move_from_ptr_fields<T>(
_ptrs, std::move(_args)...,
move_from_ptr_fields<U>(std::get<i>(_ptrs)));
}
}
}
/// Creates a struct of type T from a named tuple by moving the underlying
/// fields.
template <class T, class NamedTupleType>
T move_from_named_tuple(NamedTupleType&& _n) {
using RequiredType = std::remove_cvref_t<named_tuple_t<T>>;
if constexpr (is_named_tuple_v<std::remove_cvref_t<T>>) {
return std::move(_n);
} else if constexpr (std::is_same<std::remove_cvref_t<NamedTupleType>,
RequiredType>()) {
auto ptr_named_tuple = nt_to_ptr_named_tuple(_n);
using PtrFieldTupleType = std::remove_cvref_t<ptr_field_tuple_t<T>>;
auto pointers = make_ptr_fields<PtrFieldTupleType>(ptr_named_tuple);
return move_from_ptr_fields<T>(pointers);
} else {
return move_from_named_tuple<T, RequiredType>(RequiredType(std::move(_n)));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,133 @@
#ifndef RFL_MOVE_FROM_TUPLE_HPP_
#define RFL_MOVE_FROM_TUPLE_HPP_
#include <functional>
#include <type_traits>
#include "Array.hpp"
#include "is_flatten_field.hpp"
#include "is_named_tuple.hpp"
#include "ptr_tuple_t.hpp"
#include "tup_to_ptr_tuple.hpp"
#include "tuple_t.hpp"
namespace rfl {
namespace internal {
template <class Tuple, int _i = 0>
constexpr int calc_flattened_size() {
if constexpr (_i == std::tuple_size_v<Tuple>) {
return 0;
} else {
using T = std::remove_pointer_t<std::tuple_element_t<_i, Tuple>>;
if constexpr (is_flatten_field_v<T>) {
return calc_flattened_size<ptr_tuple_t<typename T::Type>>() +
calc_flattened_size<Tuple, _i + 1>();
} else {
return 1 + calc_flattened_size<Tuple, _i + 1>();
}
}
}
template <class TargetTupleType, class PtrTupleType, int _j = 0, class... Args>
auto unflatten_ptr_tuple(PtrTupleType& _t, Args... _args) {
constexpr auto i = sizeof...(Args);
constexpr auto size = std::tuple_size_v<std::remove_cvref_t<TargetTupleType>>;
if constexpr (i == size) {
return std::make_tuple(_args...);
} else {
using T = std::remove_cvref_t<
std::remove_pointer_t<std::tuple_element_t<i, TargetTupleType>>>;
if constexpr (is_flatten_field_v<T>) {
using SubTargetTupleType =
ptr_tuple_t<std::remove_pointer_t<typename T::Type>>;
constexpr int flattened_size = calc_flattened_size<SubTargetTupleType>();
return unflatten_ptr_tuple<TargetTupleType, PtrTupleType,
_j + flattened_size>(
_t, _args...,
unflatten_ptr_tuple<SubTargetTupleType, PtrTupleType, _j>(_t));
} else {
return unflatten_ptr_tuple<TargetTupleType, PtrTupleType, _j + 1>(
_t, _args..., std::get<_j>(_t));
}
}
}
template <class T, class Pointers, class... Args>
auto move_from_pointers(Pointers& _ptrs, Args&&... _args) {
constexpr auto i = sizeof...(Args);
if constexpr (i == std::tuple_size_v<std::remove_cvref_t<Pointers>>) {
return std::remove_cvref_t<T>{std::move(_args)...};
} else {
using FieldType = std::tuple_element_t<i, std::remove_cvref_t<Pointers>>;
if constexpr (std::is_pointer_v<FieldType>) {
return move_from_pointers<T>(_ptrs, std::move(_args)...,
std::move(*std::get<i>(_ptrs)));
} else {
using PtrTupleType = ptr_tuple_t<std::remove_cvref_t<T>>;
using U = std::remove_cvref_t<typename std::remove_pointer_t<
typename std::tuple_element_t<i, PtrTupleType>>::Type>;
return move_from_pointers<T>(_ptrs, std::move(_args)...,
move_from_pointers<U>(std::get<i>(_ptrs)));
}
}
}
template <class T>
auto flatten_array(T* _v) {
return std::make_tuple(_v);
}
template <class T, std::size_t _n>
auto flatten_array(std::array<T, _n>* _arr) {
const auto fct = [](auto&... _v) {
return std::tuple_cat(flatten_array(&_v)...);
};
return std::apply(fct, *_arr);
}
template <class T>
auto make_tuple_from_element(T _v) {
return std::make_tuple(_v);
}
template <class T>
auto make_tuple_from_element(Array<T>* _arr) {
return flatten_array(&(_arr->arr_));
}
auto flatten_c_arrays(const auto& _tup) {
const auto fct = [](auto... _v) {
return std::tuple_cat(make_tuple_from_element(_v)...);
};
return std::apply(fct, _tup);
}
/// Creates a struct of type T from a tuple by moving the underlying
/// fields.
template <class T, class TupleType>
auto move_from_tuple(TupleType&& _t) {
auto ptr_tuple = tup_to_ptr_tuple(_t);
using TargetTupleType = tuple_t<std::remove_cvref_t<T>>;
auto pointers =
flatten_c_arrays(unflatten_ptr_tuple<TargetTupleType>(ptr_tuple));
return move_from_pointers<T>(pointers);
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,45 @@
#ifndef RFL_INTERNAL_MOVE_TO_FIELD_TUPLE_HPP_
#define RFL_INTERNAL_MOVE_TO_FIELD_TUPLE_HPP_
#include <tuple>
#include <type_traits>
#include "../field_names_t.hpp"
#include "Array.hpp"
#include "bind_to_tuple.hpp"
#include "has_fields.hpp"
#include "is_empty.hpp"
#include "is_named_tuple.hpp"
#include "wrap_in_fields.hpp"
namespace rfl {
namespace internal {
template <class OriginalStruct>
auto move_to_field_tuple(OriginalStruct&& _t) {
using T = std::remove_cvref_t<OriginalStruct>;
if constexpr (is_named_tuple_v<T>) {
return _t.fields();
} else if constexpr (has_fields<T>()) {
return bind_to_tuple(_t, [](auto& x) { return std::move(x); });
} else if constexpr (is_empty<T>()) {
return std::tuple();
} else {
using FieldNames = field_names_t<T>;
const auto fct = []<class T>(T& _v) {
using Type = std::remove_cvref_t<T>;
if constexpr (std::is_array_v<Type>) {
return Array<Type>(_v);
} else {
return std::move(_v);
}
};
auto tup = bind_to_tuple(_t, fct);
return wrap_in_fields<FieldNames>(std::move(tup));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,41 @@
#ifndef RFL_INTERNAL_NO_DUPLICATE_FIELD_NAMES_HPP_
#define RFL_INTERNAL_NO_DUPLICATE_FIELD_NAMES_HPP_
#include <tuple>
namespace rfl {
namespace internal {
template <class Fields, int _i = 1, int _j = 0>
constexpr inline bool no_duplicate_field_names() {
constexpr auto num_fields = std::tuple_size_v<Fields>;
if constexpr (num_fields <= 1) {
return true;
} else {
if constexpr (_i == num_fields) {
return true;
} else if constexpr (_j == -1) {
return no_duplicate_field_names<Fields, _i + 1, _i>();
} else {
using FieldType1 =
std::remove_cvref_t<typename std::tuple_element<_i, Fields>::type>;
using FieldType2 =
std::remove_cvref_t<typename std::tuple_element<_j, Fields>::type>;
constexpr auto field_name_i = FieldType1::name_;
constexpr auto field_name_j = FieldType2::name_;
constexpr bool no_duplicate = (field_name_i != field_name_j);
static_assert(no_duplicate, "Duplicate field names are not allowed");
return no_duplicate && no_duplicate_field_names<Fields, _i, _j - 1>();
}
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,54 @@
#ifndef RFL_INTERNAL_NT_TO_PTR_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_NT_TO_PTR_NAMED_TUPLE_HPP_
#include <tuple>
#include "../Field.hpp"
#include "../make_named_tuple.hpp"
namespace rfl {
namespace internal {
/// Generates a named tuple that contains pointers to the original values in
/// the struct from a named tuple.
template <class NamedTupleType, class... AlreadyExtracted>
auto nt_to_ptr_named_tuple(NamedTupleType& _nt, AlreadyExtracted... _a) {
using Fields = typename NamedTupleType::Fields;
constexpr auto i = sizeof...(AlreadyExtracted);
constexpr auto num_fields = std::tuple_size_v<Fields>;
if constexpr (i == num_fields) {
return make_named_tuple(_a...);
} else {
using FieldType = typename std::tuple_element<i, Fields>::type;
using T = std::remove_cvref_t<typename FieldType::Type>;
return nt_to_ptr_named_tuple(
_nt, _a..., Field<FieldType::name_, T*>(&std::get<i>(_nt.values())));
}
}
/// Generates a named tuple that contains pointers to the original values in
/// the struct from a named tuple.
template <class NamedTupleType, class... AlreadyExtracted>
auto nt_to_ptr_named_tuple(const NamedTupleType& _nt, AlreadyExtracted... _a) {
using Fields = typename NamedTupleType::Fields;
constexpr auto i = sizeof...(AlreadyExtracted);
constexpr auto num_fields = std::tuple_size_v<Fields>;
if constexpr (i == num_fields) {
return make_named_tuple(_a...);
} else {
using FieldType = typename std::tuple_element<i, Fields>::type;
using T = std::remove_cvref_t<typename FieldType::Type>;
return nt_to_ptr_named_tuple(
_nt, _a...,
Field<FieldType::name_, const T*>(&std::get<i>(_nt.values())));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,214 @@
#ifndef RFL_INTERNAL_NUM_FIELDS_HPP_
#define RFL_INTERNAL_NUM_FIELDS_HPP_
/*
We infer the number of fields using by figuring out how many fields
we need to construct it. This is done by implementing the constructible
concept, see below.
However, there is a problem with C arrays. Suppose you have a struct
like this:
struct A{
int arr[3];
};
Then, the struct can be initialized like this:
const auto a = A{1, 2, 3};
This is a problem, because a naive logic would believe that A
has three fields, when in fact it has only one.
That is why we use the constructible concept to get the maximum
possible number of fields and then try to subdivide them into arrays
in order to figure out which of these fields is in fact an array.
Basically, for every field there is, we try to squeeze as many variables into
the potential array as we can without missing variables in subsequent fields.
This is the purpose of get_nested_array_size().
*/
#include <algorithm>
#include <cstddef>
#include <type_traits>
#include <utility>
#if __GNUC__
#ifndef __clang__
#pragma GCC system_header
#endif
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"
#pragma clang diagnostic ignored "-Wundefined-inline"
#endif
namespace rfl {
namespace internal {
template <class Derived>
struct any_empty_base {
any_empty_base(std::size_t);
template <class Base>
requires(
std::is_empty_v<std::remove_cvref_t<Base>> &&
std::is_base_of_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>, std::remove_cv_t<Derived>>)
constexpr operator Base&() const noexcept;
};
template <class Derived>
struct any_base {
any_base(std::size_t);
template <class Base>
requires(
std::is_base_of_v<std::remove_cvref_t<Base>,
std::remove_cv_t<Derived>> &&
!std::is_same_v<std::remove_cvref_t<Base>, std::remove_cv_t<Derived>>)
constexpr operator Base&() const noexcept;
};
struct any {
any(std::size_t);
template <typename T>
constexpr operator T() const noexcept;
};
template <typename T>
struct CountFieldsHelper {
template <std::size_t n>
static consteval bool constructible() {
return []<std::size_t... is>(std::index_sequence<is...>) {
return requires { T{any(is)...}; };
}
(std::make_index_sequence<n>());
}
template <std::size_t l, std::size_t nested, std::size_t r>
static consteval bool constructible_with_nested() {
return []<std::size_t... i, std::size_t... j, std::size_t... k>(
std::index_sequence<i...>, std::index_sequence<j...>,
std::index_sequence<k...>) {
return requires { T{any(i)..., {any(j)...}, any(k)...}; };
}
(std::make_index_sequence<l>(), std::make_index_sequence<nested>(),
std::make_index_sequence<r>());
}
template <std::size_t n = 0>
static consteval std::size_t count_max_args_in_agg_init() {
static_assert(n <= static_cast<std::size_t>(sizeof(T)));
if constexpr (constructible<n>() && !constructible<n + 1>()) {
return n;
} else {
return count_max_args_in_agg_init<n + 1>();
}
}
template <std::size_t index, std::size_t size, std::size_t rest>
static consteval std::size_t get_nested_array_size() {
if constexpr (size < 1) {
return 1;
} else if constexpr (constructible_with_nested<index, size, rest>() &&
!constructible_with_nested<index, size, rest + 1>()) {
return size;
} else {
return get_nested_array_size<index, size - 1, rest + 1>();
}
}
template <std::size_t max_args, std::size_t index = 0>
static consteval std::size_t find_the_sole_non_empty_base_index() {
static_assert(index < max_args);
constexpr auto check = []<std::size_t... l, std::size_t... r>(
std::index_sequence<l...>,
std::index_sequence<r...>) {
return requires {
T{any_empty_base<T>(l)..., any_base<T>(0), any_empty_base<T>(r)...};
};
};
if constexpr (check(std::make_index_sequence<index>(),
std::make_index_sequence<max_args - index - 1>())) {
return index;
} else {
return find_the_sole_non_empty_base_index<max_args, index + 1>();
}
}
template <std::size_t arg_index, std::size_t size = 0>
static consteval std::size_t get_nested_base_field_count() {
static_assert(size <= sizeof(T));
if constexpr (constructible_with_nested<arg_index, size, 0>() &&
!constructible_with_nested<arg_index, size + 1, 0>()) {
return size;
} else {
return get_nested_base_field_count<arg_index, size + 1>();
}
}
template <std::size_t n, std::size_t max_arg_num>
static consteval bool has_n_base_param() {
constexpr auto right_len = max_arg_num>=n ? max_arg_num-n : 0;
return []<std::size_t... l, std::size_t... r>(std::index_sequence<l...>,
std::index_sequence<r...>) {
return requires { T{any_base<T>(l)..., any(r)...}; };
}(std::make_index_sequence<n>(), std::make_index_sequence<right_len>());
}
template <std::size_t max_arg_num, std::size_t index = 0>
static consteval std::size_t base_param_num() {
if constexpr (!has_n_base_param<index + 1, max_arg_num>()) {
return index;
} else {
return base_param_num<max_arg_num, index + 1>();
}
}
template <std::size_t index, std::size_t max>
static consteval std::size_t constructible_no_brace_elision() {
static_assert(index <= max);
if constexpr (index == max) {
return 0;
} else {
return 1 +
constructible_no_brace_elision<
index + get_nested_array_size<index, max - index, 0>(), max>();
}
}
static consteval std::size_t count_fields() {
constexpr std::size_t max_agg_args = count_max_args_in_agg_init();
constexpr std::size_t no_brace_ellison_args =
constructible_no_brace_elision<0, max_agg_args>();
constexpr std::size_t base_args = base_param_num<no_brace_ellison_args>();
if constexpr (no_brace_ellison_args == 0 && base_args == 0) {
// Empty struct
return 0;
} else if constexpr (base_args == no_brace_ellison_args) {
// Special case when the derived class is empty.
// In such cases the filed number is the fields in base class.
// Note that there should be only one base class in this case.
return get_nested_base_field_count<
find_the_sole_non_empty_base_index<max_agg_args>()>();
} else {
return no_brace_ellison_args - base_args;
}
}
};
template <class T>
constexpr std::size_t num_fields = CountFieldsHelper<T>::count_fields();
} // namespace internal
} // namespace rfl
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif

View file

@ -0,0 +1,27 @@
#ifndef RFL_INTERNAL_PROCESSED_T_HPP_
#define RFL_INTERNAL_PROCESSED_T_HPP_
#include <type_traits>
#include "../Processors.hpp"
#include "../named_tuple_t.hpp"
namespace rfl::internal {
template <class StructType, class ProcessorsType>
struct Processed;
template <class StructType, class... Ps>
struct Processed<StructType, Processors<Ps...>> {
using NamedTupleType = named_tuple_t<StructType>;
using type = typename std::invoke_result<
decltype(Processors<Ps...>::template process<StructType, NamedTupleType>),
NamedTupleType>::type;
};
template <class StructType, class ProcessorsType>
using processed_t = typename Processed<StructType, ProcessorsType>::type;
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,19 @@
#ifndef RFL_INTERNAL_PTR_NAMED_TUPLE_T_HPP_
#define RFL_INTERNAL_PTR_NAMED_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "to_ptr_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using ptr_field_tuple_t = decltype(to_ptr_field_tuple(std::declval<T&>()));
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,21 @@
#ifndef RFL_INTERNAL_PTR_FIELD_TUPLE_T_HPP_
#define RFL_INTERNAL_PTR_FIELD_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "is_named_tuple.hpp"
#include "to_ptr_named_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using ptr_named_tuple_t =
typename std::invoke_result<decltype(to_ptr_named_tuple<T>), T>::type;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,18 @@
#ifndef RFL_INTERNAL_PTR_TUPLE_T_HPP_
#define RFL_INTERNAL_PTR_TUPLE_T_HPP_
#include <functional>
#include <type_traits>
#include "to_ptr_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using ptr_tuple_t = decltype(to_ptr_tuple(std::declval<T&>()));
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,83 @@
#ifndef RFL_INTERNAL_REMOVEFIELDS_HPP_
#define RFL_INTERNAL_REMOVEFIELDS_HPP_
#include <algorithm>
#include <tuple>
#include <type_traits>
#include "../NamedTuple.hpp"
#include "../define_named_tuple.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
/// Recursively builds a new NamedTuple type from the FieldTypes, leaving out
/// the field signified by _name.
template <class _OldNamedTupleType, StringLiteral _name,
class _NewNamedTupleType, int _i>
struct remove_single_field;
/// Special case - _i == 0
template <class _OldNamedTupleType, StringLiteral _name,
class _NewNamedTupleType>
struct remove_single_field<_OldNamedTupleType, _name, _NewNamedTupleType, 0> {
using type = _NewNamedTupleType;
};
/// General case.
template <class _OldNamedTupleType, StringLiteral _name,
class _NewNamedTupleType, int _i>
struct remove_single_field {
using OldNamedTupleType = std::remove_cvref_t<_OldNamedTupleType>;
constexpr static int num_fields =
std::tuple_size_v<typename OldNamedTupleType::Fields>;
using FieldType = std::remove_cvref_t<typename std::tuple_element<
num_fields - _i, typename OldNamedTupleType::Fields>::type>;
using NewNamedTupleType =
std::conditional_t<_name == FieldType::name_, _NewNamedTupleType,
define_named_tuple_t<_NewNamedTupleType, FieldType>>;
using type = typename remove_single_field<OldNamedTupleType, _name,
NewNamedTupleType, _i - 1>::type;
};
/// Recursively removes all of the fields signified by _head and _tail from the
/// NamedTupleType.
template <class _NamedTupleType, StringLiteral _head, StringLiteral... _tail>
struct remove_fields;
/// Special case - only head is left.
template <class _NamedTupleType, StringLiteral _head>
struct remove_fields<_NamedTupleType, _head> {
using NamedTupleType = std::remove_cvref_t<_NamedTupleType>;
constexpr static int num_fields =
std::tuple_size_v<typename NamedTupleType::Fields>;
using type = typename remove_single_field<NamedTupleType, _head, NamedTuple<>,
num_fields>::type;
};
/// General case.
template <class _NamedTupleType, StringLiteral _head, StringLiteral... _tail>
struct remove_fields {
using NamedTupleType = std::remove_cvref_t<_NamedTupleType>;
constexpr static int num_fields =
std::tuple_size_v<typename NamedTupleType::Fields>;
using NewNamedTupleType =
typename remove_single_field<NamedTupleType, _head, NamedTuple<>,
num_fields>::type;
using type = typename remove_fields<NewNamedTupleType, _tail...>::type;
};
} // namespace internal
} // namespace rfl
#endif // RFL_REMOVEFIELDS_HPP_

View file

@ -0,0 +1,30 @@
#ifndef RFL_INTERNAL_REMOVE_NAMESPACES_HPP_
#define RFL_INTERNAL_REMOVE_NAMESPACES_HPP_
#include <source_location>
#include <string_view>
#include <utility>
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <StringLiteral _name>
consteval auto remove_namespaces() {
constexpr auto name = _name.string_view();
constexpr size_t pos = name.find_last_of(":");
if constexpr (pos == std::string_view::npos) {
return _name;
}
constexpr auto substr = name.substr(pos + 1);
const auto to_str_lit = [&]<auto... Ns>(std::index_sequence<Ns...>) {
return StringLiteral<sizeof...(Ns) + 1>{substr[Ns]...};
};
return to_str_lit(std::make_index_sequence<substr.size()>{});
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,26 @@
#ifndef RFL_INTERNAL_REMOVE_PTRS_TUP_HPP_
#define RFL_INTERNAL_REMOVE_PTRS_TUP_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "ptr_tuple_t.hpp"
#include "../to_named_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
struct remove_ptrs_tup;
template <class... Ts>
struct remove_ptrs_tup<std::tuple<Ts...>> {
using TupleType =
std::tuple<std::remove_cvref_t<std::remove_pointer_t<Ts>>...>;
};
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_STRINGS_JOIN_HPP_
#define RFL_INTERNAL_STRINGS_JOIN_HPP_
#include <string>
#include <vector>
namespace rfl {
namespace internal {
namespace strings {
/// Joins a string using the delimiter
inline std::string join(const std::string& _delimiter,
const std::vector<std::string>& _strings) {
if (_strings.size() == 0) {
return "";
}
auto res = _strings[0];
for (size_t i = 1; i < _strings.size(); ++i) {
res += _delimiter + _strings[i];
}
return res;
}
} // namespace strings
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_STRINGS_REPLACE_ALL_HPP_
#define RFL_INTERNAL_STRINGS_REPLACE_ALL_HPP_
#include <string>
#include <vector>
namespace rfl {
namespace internal {
namespace strings {
inline std::string replace_all(const std::string& _str,
const std::string& _from,
const std::string& _to) {
auto str = _str;
size_t pos = 0;
while ((pos = str.find(_from, pos)) != std::string::npos) {
str.replace(pos, _from.length(), _to);
pos += _to.length();
}
return str;
}
} // namespace strings
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_STRINGS_SPLIT_HPP_
#define RFL_INTERNAL_STRINGS_SPLIT_HPP_
#include <string>
#include <vector>
namespace rfl {
namespace internal {
namespace strings {
/// Splits a string alongside the delimiter
inline std::vector<std::string> split(const std::string& _str,
const std::string& _delimiter) {
auto str = _str;
size_t pos = 0;
std::vector<std::string> result;
while ((pos = str.find(_delimiter)) != std::string::npos) {
result.emplace_back(str.substr(0, pos));
str.erase(0, pos + _delimiter.length());
}
result.emplace_back(std::move(str));
return result;
}
} // namespace strings
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,17 @@
#ifndef RFL_INTERNAL_TAG_T_HPP_
#define RFL_INTERNAL_TAG_T_HPP_
#include <type_traits>
#include "StringLiteral.hpp"
#include "make_tag.hpp"
namespace rfl::internal {
template <internal::StringLiteral _discriminator, class T>
using tag_t =
typename std::invoke_result<decltype(make_tag<_discriminator, T>), T>::type;
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,42 @@
#ifndef RFL_INTERNAL_TO_FLATTENED_PTR_TUPLE_HPP_
#define RFL_INTERNAL_TO_FLATTENED_PTR_TUPLE_HPP_
#include <tuple>
#include "has_flatten_fields.hpp"
#include "is_flatten_field.hpp"
#include "to_ptr_tuple.hpp"
namespace rfl {
namespace internal {
template <class PtrTuple, class... Args>
auto flatten_ptr_tuple(PtrTuple&& _t, Args... _args) {
constexpr auto i = sizeof...(Args);
if constexpr (i == 0 && !has_flatten_fields<PtrTuple>()) {
return std::forward<PtrTuple>(_t);
} else if constexpr (i == std::tuple_size_v<std::remove_cvref_t<PtrTuple>>) {
return std::tuple_cat(std::forward<Args>(_args)...);
} else {
using T = std::tuple_element_t<i, std::remove_cvref_t<PtrTuple>>;
if constexpr (is_flatten_field_v<T>) {
return flatten_ptr_tuple(
std::forward<PtrTuple>(_t), std::forward<Args>(_args)...,
flatten_ptr_tuple(to_ptr_tuple(std::get<i>(_t)->get())));
} else {
return flatten_ptr_tuple(std::forward<PtrTuple>(_t),
std::forward<Args>(_args)...,
std::make_tuple(std::get<i>(_t)));
}
}
}
template <class T>
auto to_flattened_ptr_tuple(T&& _t) {
return flatten_ptr_tuple(to_ptr_tuple(_t));
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,41 @@
#ifndef RFL_INTERNAL_TOPTRFIELD_HPP_
#define RFL_INTERNAL_TOPTRFIELD_HPP_
#include <type_traits>
#include "../Field.hpp"
#include "../Flatten.hpp"
#include "../always_false.hpp"
#include "StringLiteral.hpp"
namespace rfl {
namespace internal {
template <internal::StringLiteral _name, class Type>
inline auto to_ptr_field(Field<_name, Type>& _field) {
using T = std::remove_reference_t<Type>;
return Field<_name, T*>(&_field.value_);
}
template <internal::StringLiteral _name, class Type>
inline auto to_ptr_field(const Field<_name, Type>& _field) {
using T = std::remove_cvref_t<Type>;
return Field<_name, const T*>(&_field.value_);
}
template <class Type>
inline auto to_ptr_field(Flatten<Type>& _field) {
using T = std::remove_reference_t<Type>;
return Flatten<T*>(&_field.value_);
}
template <class Type>
inline auto to_ptr_field(const Flatten<Type>& _field) {
using T = std::remove_cvref_t<Type>;
return Flatten<const T*>(&_field.value_);
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,40 @@
#ifndef RFL_INTERNAL_TO_PTR_FIELD_TUPLE_HPP_
#define RFL_INTERNAL_TO_PTR_FIELD_TUPLE_HPP_
#include <iostream>
#include <tuple>
#include <type_traits>
#include "../field_names_t.hpp"
#include "bind_to_tuple.hpp"
#include "has_fields.hpp"
#include "is_empty.hpp"
#include "is_named_tuple.hpp"
#include "nt_to_ptr_named_tuple.hpp"
#include "to_ptr_field.hpp"
#include "wrap_in_fields.hpp"
namespace rfl {
namespace internal {
template <class T>
auto to_ptr_field_tuple(T& _t) {
if constexpr (std::is_pointer_v<std::remove_cvref_t<T>>) {
return to_ptr_field_tuple(*_t);
} else if constexpr (is_named_tuple_v<T>) {
return nt_to_ptr_named_tuple(_t).fields();
} else if constexpr (has_fields<T>()) {
return bind_to_tuple(_t, [](auto& x) { return to_ptr_field(x); });
} else if constexpr (is_empty<T>()) {
return std::tuple();
} else {
using FieldNames = field_names_t<T>;
auto tup = bind_to_tuple(_t, [](auto& x) { return to_ptr_field(x); });
return wrap_in_fields<FieldNames>(std::move(tup));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,79 @@
#ifndef RFL_INTERNAL_TO_PTR_NAMED_TUPLE_HPP_
#define RFL_INTERNAL_TO_PTR_NAMED_TUPLE_HPP_
#include <iostream>
#include <tuple>
#include "../always_false.hpp"
#include "../field_names_t.hpp"
#include "../make_named_tuple.hpp"
#include "copy_flattened_tuple_to_named_tuple.hpp"
#include "has_fields.hpp"
#include "has_flatten_fields.hpp"
#include "is_empty.hpp"
#include "is_field.hpp"
#include "is_named_tuple.hpp"
#include "to_flattened_ptr_tuple.hpp"
#include "to_ptr_field_tuple.hpp"
namespace rfl {
namespace internal {
template <class PtrFieldTuple, class... Args>
auto flatten_ptr_field_tuple(PtrFieldTuple& _t, Args&&... _args) {
constexpr auto i = sizeof...(Args);
if constexpr (i == std::tuple_size_v<std::remove_cvref_t<PtrFieldTuple>>) {
return std::tuple_cat(std::forward<Args>(_args)...);
} else {
using T = std::tuple_element_t<i, std::remove_cvref_t<PtrFieldTuple>>;
if constexpr (internal::is_flatten_field<T>::value) {
auto subtuple = internal::to_ptr_field_tuple(*std::get<i>(_t).get());
return flatten_ptr_field_tuple(_t, std::forward<Args>(_args)...,
flatten_ptr_field_tuple(subtuple));
} else {
return flatten_ptr_field_tuple(_t, std::forward<Args>(_args)...,
std::make_tuple(std::get<i>(_t)));
}
}
}
template <class PtrFieldTuple>
auto field_tuple_to_named_tuple(PtrFieldTuple& _ptr_field_tuple) {
const auto ft_to_nt = []<class... Fields>(Fields&&... _fields) {
return make_named_tuple(_fields...);
};
if constexpr (!has_flatten_fields<std::remove_cvref_t<PtrFieldTuple>>()) {
return std::apply(ft_to_nt, std::move(_ptr_field_tuple));
} else {
const auto flattened_tuple = flatten_ptr_field_tuple(_ptr_field_tuple);
return std::apply(ft_to_nt, flattened_tuple);
}
}
/// Generates a named tuple that contains pointers to the original values in
/// the struct.
template <class T>
auto to_ptr_named_tuple(T&& _t) {
if constexpr (has_fields<std::remove_cvref_t<T>>()) {
if constexpr (std::is_pointer_v<std::remove_cvref_t<T>>) {
return to_ptr_named_tuple(*_t);
} else if constexpr (is_named_tuple_v<std::remove_cvref_t<T>>) {
return nt_to_ptr_named_tuple(_t);
} else {
auto ptr_field_tuple = to_ptr_field_tuple(_t);
return field_tuple_to_named_tuple(ptr_field_tuple);
}
} else if constexpr (is_empty<T>()) {
return rfl::NamedTuple<>();
} else {
using FieldNames = rfl::field_names_t<T>;
auto flattened_ptr_tuple = to_flattened_ptr_tuple(_t);
return copy_flattened_tuple_to_named_tuple<FieldNames>(flattened_ptr_tuple);
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,25 @@
#ifndef RFL_INTERNAL_TO_PTR_TUPLE_HPP_
#define RFL_INTERNAL_TO_PTR_TUPLE_HPP_
#include <iostream>
#include <tuple>
#include <type_traits>
#include "bind_to_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
constexpr auto to_ptr_tuple(T& _t) {
if constexpr (std::is_pointer_v<std::remove_cvref_t<T>>) {
return to_ptr_tuple(*_t);
} else {
return bind_to_tuple(_t, [](auto& x) { return &x; });
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,57 @@
#ifndef RFL_INTERNAL_TO_STD_ARRAY_HPP_
#define RFL_INTERNAL_TO_STD_ARRAY_HPP_
#include <array>
#include <cstdint>
#include <type_traits>
namespace rfl::internal {
template <class T>
struct StdArrayType {
using Type = T;
};
template <class T, size_t _n>
struct StdArrayType<T[_n]> {
using Type =
std::array<typename StdArrayType<std::remove_cvref_t<T>>::Type, _n>;
using ValueType = std::remove_cvref_t<T>;
constexpr static size_t size = _n;
};
template <class T>
using to_std_array_t = StdArrayType<T>::Type;
template <class T>
auto to_std_array(T&& _t) {
using Type = std::remove_cvref_t<T>;
if constexpr (std::is_array_v<Type>) {
constexpr size_t n = StdArrayType<Type>::size;
const auto fct = [&]<std::size_t... _i>(std::index_sequence<_i...>) {
return to_std_array_t<Type>({to_std_array(
std::forward<typename StdArrayType<Type>::ValueType>(_t[_i]))...});
};
return fct(std::make_index_sequence<n>());
} else {
return std::forward<T>(_t);
}
}
template <class T>
auto to_std_array(const T& _t) {
using Type = std::remove_cvref_t<T>;
if constexpr (std::is_array_v<Type>) {
constexpr size_t n = StdArrayType<Type>::size;
const auto fct = [&]<std::size_t... _i>(std::index_sequence<_i...>) {
return to_std_array_t<Type>({to_std_array(_t[_i])...});
};
return fct(std::make_index_sequence<n>());
} else {
return _t;
}
}
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,38 @@
#ifndef RFL_INTERNAL_TRANSFORMSNAKECASE_HPP_
#define RFL_INTERNAL_TRANSFORMSNAKECASE_HPP_
#include "StringLiteral.hpp"
namespace rfl::internal {
/// Capitalizes a lower-case character.
template <char c>
consteval char to_upper() {
if constexpr (c >= 'a' && c <= 'z') {
return c + ('A' - 'a');
} else {
return c;
}
}
/// Transforms the field name from snake case to camel case.
template <internal::StringLiteral _name, bool _capitalize, size_t _i = 0,
char... chars>
consteval auto transform_snake_case() {
if constexpr (_i == _name.arr_.size()) {
return StringLiteral<sizeof...(chars) + 1>(chars...);
} else if constexpr (_name.arr_[_i] == '_') {
return transform_snake_case<_name, true, _i + 1, chars...>();
} else if constexpr (_name.arr_[_i] == '\0') {
return transform_snake_case<_name, false, _name.arr_.size(), chars...>();
} else if constexpr (_capitalize) {
return transform_snake_case<_name, false, _i + 1, chars...,
to_upper<_name.arr_[_i]>()>();
} else {
return transform_snake_case<_name, false, _i + 1, chars...,
_name.arr_[_i]>();
}
}
} // namespace rfl::internal
#endif

View file

@ -0,0 +1,29 @@
#ifndef RFL_INTERNAL_TUP_TO_PTR_TUPLE_HPP_
#define RFL_INTERNAL_TUP_TO_PTR_TUPLE_HPP_
#include <tuple>
#include "../Field.hpp"
#include "../make_named_tuple.hpp"
namespace rfl {
namespace internal {
/// Generates a named tuple that contains pointers to the original values in
/// the struct from a tuple.
template <class TupleType, class... AlreadyExtracted>
auto tup_to_ptr_tuple(TupleType& _t, AlreadyExtracted... _a) {
constexpr auto i = sizeof...(AlreadyExtracted);
constexpr auto size = std::tuple_size_v<TupleType>;
if constexpr (i == size) {
return std::make_tuple(_a...);
} else {
return tup_to_ptr_tuple(_t, _a..., &std::get<i>(_t));
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,21 @@
#ifndef RFL_INTERNAL_TUPLE_T_HPP_
#define RFL_INTERNAL_TUPLE_T_HPP_
#include <functional>
#include <tuple>
#include <type_traits>
#include "ptr_tuple_t.hpp"
#include "remove_ptrs_tup.hpp"
#include "../to_named_tuple.hpp"
namespace rfl {
namespace internal {
template <class T>
using tuple_t = typename remove_ptrs_tup<ptr_tuple_t<T>>::TupleType;
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,44 @@
#ifndef RFL_INTERNAL_WRAP_IN_FIELDS_HPP_
#define RFL_INTERNAL_WRAP_IN_FIELDS_HPP_
#include <tuple>
#include <type_traits>
#include "flattened_ptr_tuple_t.hpp"
#include "is_flatten_field.hpp"
#include "lit_name.hpp"
namespace rfl {
namespace internal {
template <class FieldNames, int j = 0, class... Fields>
auto wrap_in_fields(auto&& _tuple, Fields&&... _fields) {
constexpr auto size =
std::tuple_size_v<std::remove_cvref_t<decltype(_tuple)>>;
constexpr auto i = sizeof...(_fields);
if constexpr (i == size) {
return std::make_tuple(std::move(_fields)...);
} else {
auto value = std::move(std::get<i>(_tuple));
using Type = std::remove_cvref_t<std::remove_pointer_t<decltype(value)>>;
if constexpr (is_flatten_field_v<Type>) {
// The problem here is that the FieldNames are already flattened, but this
// is not, so we need to determine how many field names to skip.
constexpr auto n_skip = std::tuple_size_v<
std::remove_cvref_t<flattened_ptr_tuple_t<typename Type::Type>>>;
return wrap_in_fields<FieldNames, j + n_skip>(
std::move(_tuple), std::move(_fields)..., std::move(value));
} else {
const auto name_literal = FieldNames::template name_of<j>();
auto new_field = rfl::make_field<
lit_name_v<std::remove_cvref_t<decltype(name_literal)>>>(
std::move(value));
return wrap_in_fields<FieldNames, j + 1>(
std::move(_tuple), std::move(_fields)..., std::move(new_field));
}
}
}
} // namespace internal
} // namespace rfl
#endif

View file

@ -0,0 +1,28 @@
#ifndef RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_
#define RFL_INTERNAL_WRAP_IN_RFL_ARRAY_T_
#include <type_traits>
#include "Array.hpp"
namespace rfl {
namespace internal {
template <class T>
struct wrap_in_rfl_array {
using type = T;
};
template <class T>
requires std::is_array_v<T>
struct wrap_in_rfl_array<T> {
using type = Array<T>;
};
template <class T>
using wrap_in_rfl_array_t = typename wrap_in_rfl_array<T>::type;
} // namespace internal
} // namespace rfl
#endif