Skip to content

Commit

Permalink
Make unwrapped optional signals clearable
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadden committed Jan 13, 2021
1 parent b20ca9e commit 803cb00
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
30 changes: 29 additions & 1 deletion src/alia/signals/adaptors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,34 @@ disable_reads(Signal s)

// unwrap(signal), where :signal is a signal carrying a std::optional value,
// yields a signal that directly carries the value wrapped inside the optional.

template<class OptionalCapabilities>
struct unwrapper_signal_capabilities
{
};
template<class Reading, class Writing>
struct unwrapper_signal_capabilities<signal_capabilities<Reading, Writing>>
{
// If the std::optional signal is writable, then the 'unwrapped' signal
// is clearable.
typedef signal_capabilities<Reading, signal_clearable> type;
};
template<class Reading>
struct unwrapper_signal_capabilities<
signal_capabilities<Reading, signal_unwritable>>
{
// If the std::optional signal is NOT writable, then the 'unwrapped' signal
// also isn't.
typedef signal_capabilities<Reading, signal_unwritable> type;
};

template<class Wrapped>
struct unwrapper_signal : casting_signal_wrapper<
unwrapper_signal<Wrapped>,
Wrapped,
typename Wrapped::value_type::value_type>
typename Wrapped::value_type::value_type,
typename unwrapper_signal_capabilities<
typename Wrapped::capabilities>::type>
{
unwrapper_signal()
{
Expand Down Expand Up @@ -537,6 +560,11 @@ struct unwrapper_signal : casting_signal_wrapper<
{
this->wrapped_.write(std::move(value));
}
void
clear() const override
{
this->wrapped_.write(typename Wrapped::value_type());
}
};
template<class Signal>
auto
Expand Down
6 changes: 6 additions & 0 deletions unit_tests/signals/adaptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,12 @@ TEST_CASE("unwrap a duplex signal", "[signals][adaptors]")
REQUIRE(x.has_value());
REQUIRE(*x == 0);
}
{
auto x = std::optional<int>(1);
auto s = unwrap(direct(x));
clear_signal(s);
REQUIRE(!x.has_value());
}
}

TEST_CASE("signal value movement", "[signals][adaptors]")
Expand Down

0 comments on commit 803cb00

Please sign in to comment.