Open Guekka opened 1 week ago
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 98.22%. Comparing base (
d88fd97
) to head (9a1f911
).
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Thanks for working on this @Guekka.
The functionality is there, but I am still trying to understand why the static_assert fail
The function is_even_opt
in test_filter_map.cpp
returns a prvalue std::optional<int>
:
When reading from the pipeline, the temporary optional gets dereferenced in this lambda:
This returns a reference to the temporary optional's internal int
. Unfortunately, when the read_at()
call returns, the temporary optional
gets destroyed, and the returned reference is immediately dangling. (This took me a little while to figure out, but I'm very pleased that the constexpr testing picked it up!)
One solution is to try to detect the problem, by noticing when dereffing the optional-like would return an rvalue reference, and returning by value instead. Like so:
struct filter_map_fn {
// If dereffing the optional would give us an rvalue reference,
// prevent a probable dangling reference by returning by value instead
template <typename T>
using strip_rvalue_ref_t = std::conditional_t<
std::is_rvalue_reference_v<T>, std::remove_reference_t<T>, T>;
template <adaptable_sequence Seq, typename Func>
requires (std::invocable<Func&, element_t<Seq>> &&
optional_like<std::remove_cvref_t<std::invoke_result_t<Func&, element_t<Seq>>>>)
constexpr auto operator()(Seq&& seq, Func func) const
{
return flux::map(FLUX_FWD(seq), std::move(func))
.filter([](auto&& opt) { return static_cast<bool>(opt); })
.map([](auto&& opt) -> strip_rvalue_ref_t<decltype(*FLUX_FWD(opt))> {
return *FLUX_FWD(opt);
});
}
};
Making this change fixes the original lifetime problem. Unfortunately this static_assert
still fails because some new
s later in the test are never delete
d, but this is pretty easy to fix :)
Hope this helps!
Thank you @tcbrindle. Debugging why something is not constexpr is complex
Cannot reproduce the CI failure locally on Windows. Will try later on Linux
Cannot reproduce the CI failure locally on Windows. Will try later on Linux
Yeah, it seems like it only happens with libstdc++ -- both MSVC and libc++ pull in std::optional
from somewhere else
Adresses #191 The functionality is there, but I am still trying to understand why the
static_assert
fail