Closed Onlynagesha closed 2 months ago
@Onlynagesha , thanks for the contribution. I have a question, though: Could you point me to something that didn't work before the r-value overloads that works now?
As you can see, most of our tests involve items that cannot be copied, such as std::unique_ptr
or rfl::Box
. If the results weren't moved already, then most of our tests wouldn't compile. Could you explain what problem you are solving with the r-value overloads? Could you maybe provide a test that doesn't compile without the r-value overloads, but compiles once you do add them?
(I am not trying to be snarky or anything, I am honestly curious.)
@liuzicheng1987 The issue was found when I attempted to use rfl::Result
as an alternative to C++23 std::expected
. As shown in the example above, it's impossible to modify foo
inside the lambda function via a left-reference before this commit, which is inconsistent to the behavior of std::expected
.
#include <chrono>
#include <expected>
#include <fmt/color.h>
#include <iostream>
#include <rfl/Result.hpp>
struct VeryLarge {
static inline auto default_ctor_count = 0;
VeryLarge() : value(std::to_string(default_ctor_count++)) {
std::cout << "Default constructor: VeryLarge()\n";
}
VeryLarge(VeryLarge&& other) noexcept : value(std::move(other.value)) {
std::cout << fmt::format(fg(fmt::color::yellow), "Move constructor: VeryLarge(VeryLarge&&)\n");
other.value = "(Moved away)";
}
VeryLarge(const VeryLarge& other) : value(other.value) {
std::cout << fmt::format(fg(fmt::color::orange), "Copy constructor: VeryLarge(const VeryLarge&)\n");
}
std::string value;
};
// Expects consistent behavior.
template <class T>
using ResultType = rfl::Result<T>;
// using ResultType = std::expected<T, rfl::Error>;
auto some_func() -> ResultType<VeryLarge> {
return VeryLarge{};
}
int main() {
auto foo = some_func();
std::cout << fmt::format("Before foo.and_then(): foo.value = {:?}\n", (*foo).value);
// Here we attempt to modify the contents inside foo via a left-reference.
foo.and_then([](VeryLarge& obj) -> ResultType<rfl::Nothing> {
obj.value += "-modified"; // Modification here
std::cout << fmt::format("foo.and_then(): obj.value: {:?}\n", obj.value);
return rfl::Nothing{};
});
// We expect that the modification above is represented here.
std::cout << fmt::format("After foo.and_then(): foo.value: {:?}\n", (*foo).value);
// Still, for right-values, copy constructor shall not be triggered.
some_func().and_then([](VeryLarge obj) -> ResultType<rfl::Nothing> {
std::cout << fmt::format("some_func().and_then(): obj.value: {:?}\n", obj.value);
return rfl::Nothing{};
});
return 0;
}
Hi @Onlynagesha ,
sorry it took me a couple of days to get back to you. I was a bit busy with the BSON integration.
Two things:
In file included from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/AllOf.hpp:4,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl.hpp:10,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:4:
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp: In instantiation of ‘rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)> [with TOrError = rfl::Error]’:
/usr/include/c++/11/bits/invoke.h:61:36: required from ‘constexpr _Res std::__invoke_impl(std::__invoke_other, _Fn&&, _Args&& ...) [with _Res = rfl::Result<unsigned int>; _Fn = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Args = {rfl::Error&}]’
/usr/include/c++/11/bits/invoke.h:96:40: required from ‘constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Args = {rfl::Error&}; typename std::__invoke_result<_Functor, _ArgTypes>::type = rfl::Result<unsigned int>]’
/usr/include/c++/11/variant:1016:24: required from ‘static constexpr decltype(auto) std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int, __indices ...> >::__visit_invoke(_Visitor&&, _Variants ...) [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {1}]’
/usr/include/c++/11/variant:1032:28: required from ‘static constexpr auto std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int, __indices ...> >::_S_apply() [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {1}]’
/usr/include/c++/11/variant:968:56: required from ‘static constexpr void std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...), __dimensions ...>, std::integer_sequence<long unsigned int, _Idxs ...> >::_S_apply_single_alt(_Tp&, _Tp*) [with bool __do_cookie = false; long unsigned int __index = 1; _Tp = std::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> > (*)(const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&, std::variant<unsigned int, rfl::Error>&)>; _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; long unsigned int ...__dimensions = {2}; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {}]’
/usr/include/c++/11/variant:947:48: required from ‘constexpr const _Array_type std::__detail::__variant::__gen_vtable<std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >, const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&, std::variant<unsigned int, rfl::Error>&>::_S_vtable’
/usr/include/c++/11/variant:1724:45: required from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}]’
/usr/include/c++/11/variant:1761:34: required from ‘constexpr std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> = rfl::Result<unsigned int>]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:267:22: required from ‘rfl::Result<T> rfl::Result<T>::or_else(const F&) & [with F = rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>; T = unsigned int]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:42:17: required from ‘static rfl::Result<U> rfl::OneOf<C, Cs>::validate_impl(const T&, std::vector<rfl::Error>) [with T = unsigned int; Head = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Tail = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}; C = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Cs = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:17:38: required from ‘static rfl::Result<U> rfl::OneOf<C, Cs>::validate(const T&) [with T = unsigned int; C = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Cs = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Validator.hpp:50:33: required from ‘rfl::Validator<T, V, Vs>::Validator(U&&) [with U = int; typename std::enable_if<is_convertible_v<U, T>, bool>::type <anonymous> = true; T = unsigned int; V = rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >; Vs = {}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:29:70: required from here
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:262:18: error: no match for call to ‘(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>) (rfl::Error&)’
262 | return _f(_t_or_err);
| ~~^~~~~~~~~~~
In file included from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl.hpp:18,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:4:
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:36:28: note: candidate: ‘rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>’ (near match)
36 | const auto push_back = [&](Error&& _err) -> rfl::Result<T> {
| ^
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:36:28: note: conversion of argument 1 would be ill-formed:
In file included from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/AllOf.hpp:4,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl.hpp:10,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:4:
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:262:18: error: cannot bind rvalue reference of type ‘rfl::Error&&’ to lvalue of type ‘rfl::Error’
262 | return _f(_t_or_err);
| ~~^~~~~~~~~~~
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp: In instantiation of ‘rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)> [with TOrError = rfl::Error]’:
/usr/include/c++/11/bits/invoke.h:61:36: required from ‘constexpr _Res std::__invoke_impl(std::__invoke_other, _Fn&&, _Args&& ...) [with _Res = rfl::Result<unsigned int>; _Fn = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Args = {rfl::Error&}]’
/usr/include/c++/11/bits/invoke.h:96:40: required from ‘constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Args = {rfl::Error&}; typename std::__invoke_result<_Functor, _ArgTypes>::type = rfl::Result<unsigned int>]’
/usr/include/c++/11/variant:1016:24: required from ‘static constexpr decltype(auto) std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int, __indices ...> >::__visit_invoke(_Visitor&&, _Variants ...) [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {1}]’
/usr/include/c++/11/variant:1032:28: required from ‘static constexpr auto std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int, __indices ...> >::_S_apply() [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {1}]’
/usr/include/c++/11/variant:968:56: required from ‘static constexpr void std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type (*)(_Visitor, _Variants ...), __dimensions ...>, std::integer_sequence<long unsigned int, _Idxs ...> >::_S_apply_single_alt(_Tp&, _Tp*) [with bool __do_cookie = false; long unsigned int __index = 1; _Tp = std::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> > (*)(const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&, std::variant<unsigned int, rfl::Error>&)>; _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; long unsigned int ...__dimensions = {2}; _Variants = {std::variant<unsigned int, rfl::Error>&}; long unsigned int ...__indices = {}’
/usr/include/c++/11/variant:947:48: required from ‘constexpr const _Array_type std::__detail::__variant::__gen_vtable<std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >, const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&, std::variant<unsigned int, rfl::Error>&>::_S_vtable’
/usr/include/c++/11/variant:1724:45: required from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with _Result_type = std::__detail::__variant::__deduce_visit_result<rfl::Result<unsigned int> >; _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}]’
/usr/include/c++/11/variant:1761:34: required from ‘constexpr std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = const rfl::Result<unsigned int>::or_else<rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)> >(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>&) &::<lambda(TOrError&)>&; _Variants = {std::variant<unsigned int, rfl::Error>&}; std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> = rfl::Result<unsigned int>]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:267:22: required from ‘rfl::Result<T> rfl::Result<T>::or_else(const F&) & [with F = rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>; T = unsigned int]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:42:17: required from ‘static rfl::Result<U> rfl::OneOf<C, Cs>::validate_impl(const T&, std::vector<rfl::Error>) [with T = unsigned int; Head = rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >; Tail = {}; C = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Cs = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:50:41: required from ‘static rfl::Result<U> rfl::OneOf<C, Cs>::validate_impl(const T&, std::vector<rfl::Error>) [with T = unsigned int; Head = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Tail = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}; C = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Cs = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:17:38: required from ‘static rfl::Result<U> rfl::OneOf<C, Cs>::validate(const T&) [with T = unsigned int; C = rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >; Cs = {rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> >}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Validator.hpp:50:33: required from ‘rfl::Validator<T, V, Vs>::Validator(U&&) [with U = int; typename std::enable_if<is_convertible_v<U, T>, bool>::type <anonymous> = true; T = unsigned int; V = rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >; Vs = {}]’
/home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:29:70: required from here
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:262:18: error: no match for call to ‘(const rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>) (rfl::Error&)’
In file included from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl.hpp:18,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:4:
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:36:28: note: candidate: ‘rfl::OneOf<rfl::AllOf<rfl::Minimum<0>, rfl::Maximum<10> >, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >::validate_impl<unsigned int, rfl::AllOf<rfl::Minimum<40>, rfl::Maximum<130> > >(const unsigned int&, std::vector<rfl::Error>)::<lambda(rfl::Error&&)>’ (near match)
36 | const auto push_back = [&](Error&& _err) -> rfl::Result<T> {
| ^
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/OneOf.hpp:36:28: note: conversion of argument 1 would be ill-formed:
In file included from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/AllOf.hpp:4,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl.hpp:10,
from /home/ubuntu/PRs/onlynagesha/reflect-cpp/tests/json/test_one_of.cpp:4:
/home/ubuntu/PRs/onlynagesha/reflect-cpp/include/rfl/Result.hpp:262:18: error: cannot bind rvalue reference of type ‘rfl::Error&&’ to lvalue of type ‘rfl::Error’
262 | return _f(_t_or_err);
| ~~^~~~~~~~~~~
Could you take a look at this?
Again, thank you for your contribution and sorry it took me so long to get back to you on this.
Hi @Onlynagesha , the compilation here still fails...could you take a look?
Changes:
rfl::Result
, i.e.rfl::Result<T>::and_then(const F&) &&
andrfl::Result<T>::and_then(const F&) const &&
etc.operator->
forrfl::Result
andrfl::Validator