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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/rfl/Field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct Field {
/// The name of the field as a Literal type.
using Name = rfl::Literal<_name>;

/// Default constructor.
Field() = default;

/// Constructs a Field from a const reference to the value.
/// @param _value The value to store in the field
Field(const Type& _value) : value_(_value) {}
Expand Down
3 changes: 3 additions & 0 deletions include/rfl/NamedTuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class NamedTuple {
using Values = rfl::Tuple<typename std::remove_cvref_t<FieldTypes>::Type...>;

public:
/// @brief Default constructor.
NamedTuple() = default;

/// @brief Construct NamedTuple from values of each field type.
/// @param _values Rvalue references to the values for each field.
NamedTuple(typename std::remove_cvref<FieldTypes>::type::Type&&... _values)
Expand Down
62 changes: 32 additions & 30 deletions include/rfl/Validator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ template <class T, class V, class... Vs>
requires internal::HasValidation<AllOf<V, Vs...>, T>
struct Validator {
public:
using ReflectionType = T;
using ValidationType =
std::conditional_t<sizeof...(Vs) == 0, V, AllOf<V, Vs...>>;
using ValueType = T;

/// Exception-free validation from a value.
/// @param _value The value to validate
Expand All @@ -39,9 +39,9 @@ struct Validator {
}
}

/// Default constructor - validates a default-constructed T.
/// @throws std::exception if validation of the default value fails
Validator() : value_(ValidationType::validate(T()).value()) {}
/// Default constructor - if the default value is legal, assign default value,
/// else assign Error.
Validator() : value_(ValidationType::validate(T())) {}

/// Move constructor.
/// @param _other The validator to move from
Expand All @@ -54,7 +54,8 @@ struct Validator {
/// Constructs from an rvalue of T (validates the value).
/// @param _value The value to validate and wrap
/// @throws std::exception if validation fails
Validator(T&& _value) : value_(ValidationType::validate(_value).value()) {}
Validator(T&& _value)
: value_(ValidationType::validate(std::forward<T>(_value)).value()) {}

/// Constructs from a const reference to T (validates the value).
/// @param _value The value to validate and wrap
Expand Down Expand Up @@ -135,51 +136,45 @@ struct Validator {
return *this;
}

/// Equality operator for comparing with other Validators.
/// @param _other The other validator to compare with
/// @return true if the underlying values are equal
bool operator==(const Validator& _other) const {
return value() == _other.value();
}
/// When used in a boolean context, returns true if the validator contains a
/// valid value, false otherwise.
operator bool() const { return value_.has_value(); }

/// Returns the underlying object.
const T& get() const noexcept { return value_; }
const T& get() const noexcept { return *value_; }

/// Returns the underlying object.
T& get() noexcept { return value_; }
T& get() noexcept { return *value_; }

/// Returns the underlying object.
T& operator*() noexcept { return value_; }
T& operator*() noexcept { return *value_; }

/// Returns the underlying object.
const T& operator*() const noexcept { return value_; }
const T& operator*() const noexcept { return *value_; }

/// Returns the underlying object.
T& operator()() noexcept { return value_; }
T& operator()() noexcept { return value_.value(); }

/// Returns the underlying object.
const T& operator()() const noexcept { return value_; }
const T& operator()() const noexcept { return value_.value(); }

/// Pointer to the underlying value.
/// @return Pointer to the stored value
T* operator->() noexcept { return &value_; }
T* operator->() noexcept { return &(*value_); }

/// Pointer to the underlying value (const).
/// @return Const pointer to the stored value
const T* operator->() const noexcept { return &value_; }
const T* operator->() const noexcept { return &(*value_); }

/// Exposes the underlying value.
T& value() noexcept { return value_; }
T& value() noexcept { return value_.value(); }

/// Exposes the underlying value.
const T& value() const noexcept { return value_; }

/// Necessary for the serialization to work.
const T& reflection() const { return value_; }
const T& value() const noexcept { return value_.value(); }

private:
/// The underlying value.
T value_;
Result<T> value_;
};

/// Three-way comparison operator for validators with the same validation rules.
Expand All @@ -190,9 +185,12 @@ struct Validator {
/// @param _v2 The second validator to compare
/// @return The ordering relationship between the underlying values
template <class T, class V, class... Vs>
inline auto operator<=>(const Validator<T, V, Vs...>& _v1,
const Validator<T, V, Vs...>& _v2) {
return _v1.value() <=> _v2.value();
inline std::partial_ordering operator<=>(const Validator<T, V, Vs...>& _v1,
const Validator<T, V, Vs...>& _v2) {
if (!_v1 || !_v2) {
return std::partial_ordering::unordered;
}
return *_v1 <=> *_v2;
}

/// Three-way comparison operator for comparing a validator with a raw value.
Expand All @@ -204,8 +202,12 @@ inline auto operator<=>(const Validator<T, V, Vs...>& _v1,
/// @return The ordering relationship between the validator's value and the raw
/// value
template <class T, class V, class... Vs>
inline auto operator<=>(const Validator<T, V, Vs...>& _v, const T& _t) {
return _v.value() <=> _t;
inline std::partial_ordering operator<=>(const Validator<T, V, Vs...>& _v,
const T& _t) {
if (!_v) {
return std::partial_ordering::unordered;
}
return *_v <=> _t;
}

} // namespace rfl
Expand Down
38 changes: 38 additions & 0 deletions include/rfl/internal/has_const_v.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef RFL_INTERNAL_HASCONST_V_HPP_
#define RFL_INTERNAL_HASCONST_V_HPP_

#include <tuple>
#include <type_traits>

#include "../NamedTuple.hpp"
#include "../Tuple.hpp"

namespace rfl::internal {

template <class T>
struct has_const;

template <class... Fields>
struct has_const<NamedTuple<Fields...>> {
constexpr static bool value =
(std::is_const_v<std::remove_pointer_t<typename Fields::Type>> || ...);
};

template <class... Fields>
struct has_const<Tuple<Fields...>> {
constexpr static bool value =
(std::is_const_v<std::remove_pointer_t<Fields>> || ...);
};

template <class... Fields>
struct has_const<std::tuple<Fields...>> {
constexpr static bool value =
(std::is_const_v<std::remove_pointer_t<Fields>> || ...);
};

template <class T>
inline constexpr bool has_const_v = has_const<T>::value;

} // namespace rfl::internal

#endif
16 changes: 5 additions & 11 deletions include/rfl/internal/has_fields.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
#include <utility>

#include "../Tuple.hpp"
//#include "all_fields.hpp"
#include "is_field.hpp"
#include "is_flatten_field.hpp"
#include "ptr_tuple_t.hpp"
#include "is_named_tuple.hpp"
#include "ptr_tuple_t.hpp"


namespace rfl {
namespace internal {
namespace rfl::internal {

template <class TupleType>
constexpr bool all_fields_or_flatten() {
Expand All @@ -30,8 +27,7 @@ constexpr bool all_fields_or_flatten() {

return [&]<int... _is>(std::integer_sequence<int, _is...>) {
return (true && ... && is_true_for_one(std::integral_constant<int, _is>{}));
}
(std::make_integer_sequence<int, rfl::tuple_size_v<TupleType>>());
}(std::make_integer_sequence<int, rfl::tuple_size_v<TupleType>>());
}

template <class TupleType>
Expand All @@ -50,8 +46,7 @@ constexpr bool some_fields_or_flatten() {
return [&]<int... _is>(std::integer_sequence<int, _is...>) {
return (false || ... ||
is_true_for_one(std::integral_constant<int, _is>{}));
}
(std::make_integer_sequence<int, rfl::tuple_size_v<TupleType>>());
}(std::make_integer_sequence<int, rfl::tuple_size_v<TupleType>>());
}

template <class T>
Expand All @@ -74,7 +69,6 @@ constexpr bool has_fields() {
}
}

} // namespace internal
} // namespace rfl
} // namespace rfl::internal

#endif
37 changes: 37 additions & 0 deletions include/rfl/internal/remove_cvref_fields_t.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef RFL_INTERNAL_REMOVE_CVREF_FIELDS_T_HPP_
#define RFL_INTERNAL_REMOVE_CVREF_FIELDS_T_HPP_

#include <tuple>
#include <type_traits>

#include "../Field.hpp"
#include "../NamedTuple.hpp"
#include "../Tuple.hpp"

namespace rfl::internal {

template <class T>
struct remove_cvref_fields;

template <class... Fields>
struct remove_cvref_fields<NamedTuple<Fields...>> {
using Type = NamedTuple<
Field<Fields::name_, std::remove_cvref_t<typename Fields::Type>>...>;
};

template <class... Fields>
struct remove_cvref_fields<Tuple<Fields...>> {
using Type = Tuple<std::remove_cvref_t<Fields>...>;
};

template <class... Fields>
struct remove_cvref_fields<std::tuple<Fields...>> {
using Type = std::tuple<std::remove_cvref_t<Fields>...>;
};

template <class T>
using remove_cvref_fields_t = typename remove_cvref_fields<T>::Type;

} // namespace rfl::internal

#endif
13 changes: 6 additions & 7 deletions include/rfl/parsing/ArrayReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class ArrayReader {

/**
* @brief Checks if the correct number of elements has been read.
* @return An error if the number of elements is incorrect, std::nullopt otherwise.
* @return An error if the number of elements is incorrect, std::nullopt
* otherwise.
*/
std::optional<Error> check_size() const {
if (num_set_ != size_) {
Expand All @@ -49,7 +50,8 @@ class ArrayReader {
/**
* @brief Reads a variable from the input and adds it to the array.
* @param _var The input variable to read.
* @return An error if reading fails or if the array is already full, std::nullopt otherwise.
* @return An error if reading fails or if the array is already full,
* std::nullopt otherwise.
*/
std::optional<Error> read(const InputVarType& _var) const {
if (num_set_ == size_) {
Expand Down Expand Up @@ -79,11 +81,8 @@ class ArrayReader {
*/
template <class Target, class Source>
void move_to(Target* _t, Source* _s) const {
if constexpr (std::is_const_v<Target>) {
return move_to(const_cast<std::remove_const_t<Target>*>(_t), _s);
} else if constexpr (!internal::is_array_v<Source> &&
!std::is_array_v<Target>) {
::new (_t) Target(std::move(*_s));
if constexpr (!internal::is_array_v<Source> && !std::is_array_v<Target>) {
*_t = Target(std::move(*_s));
} else if constexpr (internal::is_array_v<Source>) {
for (size_t i = 0; i < _s->arr_.size(); ++i) {
move_to(&((*_t)[i]), &(_s->arr_[i]));
Expand Down
Loading
Loading