-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
151 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#ifndef ALIA_FLOW_CONDITIONALS_HPP | ||
#define ALIA_FLOW_CONDITIONALS_HPP | ||
|
||
#include <alia/flow/macros.hpp> | ||
#include <type_traits> | ||
|
||
namespace alia { | ||
|
||
template<class Context, class ComponentCallback> | ||
std::enable_if_t<is_invocable<ComponentCallback>::value> | ||
invoke_component_callback(Context, ComponentCallback&& callback) | ||
{ | ||
callback(); | ||
} | ||
|
||
template<class Context, class ComponentCallback> | ||
std::enable_if_t<is_invocable<ComponentCallback, Context>::value> | ||
invoke_component_callback(Context ctx, ComponentCallback&& callback) | ||
{ | ||
callback(ctx); | ||
} | ||
|
||
namespace detail { | ||
|
||
template<class Context> | ||
struct if_stub | ||
{ | ||
template<class Condition, class Body> | ||
if_stub | ||
else_if_(Condition condition, Body&& body); | ||
|
||
template<class Body> | ||
void | ||
else_(Body&& body); | ||
|
||
Context ctx_; | ||
bool else_condition_; | ||
}; | ||
|
||
template<class Context, class Condition, class Body> | ||
if_stub<Context> | ||
if_(Context ctx, bool inherited_condition, Condition condition, Body&& body) | ||
{ | ||
bool else_condition; | ||
|
||
ALIA_IF(inherited_condition && condition) | ||
{ | ||
invoke_component_callback(ctx, body); | ||
} | ||
// Hacking the macros... | ||
// clang-format off | ||
} | ||
else_condition = inherited_condition && _alia_else_condition; | ||
{ | ||
// clang-format on | ||
ALIA_END | ||
|
||
return if_stub<Context>{ctx, else_condition}; | ||
} | ||
|
||
template<class Context> | ||
template<class Condition, class Body> | ||
if_stub<Context> | ||
if_stub<Context>::else_if_(Condition condition, Body&& body) | ||
{ | ||
return if_(this->ctx_, this->else_condition_, condition, body); | ||
} | ||
|
||
template<class Context> | ||
template<class Body> | ||
void | ||
if_stub<Context>::else_(Body&& body) | ||
{ | ||
if_(this->ctx_, this->else_condition_, true, body); | ||
} | ||
|
||
} // namespace detail | ||
|
||
template<class Context, class Condition, class Body> | ||
detail::if_stub<Context> | ||
if_(Context ctx, Condition condition, Body&& body) | ||
{ | ||
return detail::if_(ctx, true, condition, body); | ||
} | ||
|
||
} // namespace alia | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <alia/flow/conditionals.hpp> | ||
|
||
#include <alia/signals/basic.hpp> | ||
#include <alia/signals/operators.hpp> | ||
|
||
#include <flow/testing.hpp> | ||
|
||
using namespace alia; | ||
|
||
TEST_CASE("conditional functions", "[flow][macros]") | ||
{ | ||
clear_log(); | ||
{ | ||
data_graph graph; | ||
auto make_controller = [](auto n) { | ||
return [&](context ctx) { | ||
if_(ctx, n < 0, [&]() { | ||
do_int(ctx, -1); | ||
}).else_if_(n == 0, [&] { | ||
do_int(ctx, 0); | ||
}).else_([&] { do_int(ctx, 1); }); | ||
|
||
if_(ctx, n != 17, [](auto ctx) { do_int(ctx, 2); }); | ||
}; | ||
}; | ||
|
||
do_traversal(graph, make_controller(value(-4))); | ||
check_log( | ||
"initializing int: -1;" | ||
"initializing int: 2;"); | ||
do_traversal(graph, make_controller(value(1))); | ||
check_log( | ||
"initializing int: 1;" | ||
"visiting int: 2;"); | ||
do_traversal(graph, make_controller(value(0))); | ||
check_log( | ||
"initializing int: 0;" | ||
"visiting int: 2;"); | ||
do_traversal(graph, make_controller(value(1))); | ||
check_log( | ||
"visiting int: 1;" | ||
"visiting int: 2;"); | ||
do_traversal(graph, make_controller(empty<int>())); | ||
check_log(""); | ||
} | ||
check_log( | ||
"destructing int;" | ||
"destructing int;" | ||
"destructing int;" | ||
"destructing int;"); | ||
} |