25 template<
typename keyT,
typename valueT>
35 template<
typename T,
typename mapperT,
typename keymapT, std::enable_if_t<!std::is_same<std::decay_t<T>,
36 ContainerWrapper>{},
bool> = true>
40 if constexpr (!std::is_class_v<T> && std::is_invocable_v<T, keyT>) {
52 keymap = std::forward<keymapT>(keymap)](
keyT const &key) {
65 std::function<std::nullptr_t (
keyT const& key)>
get =
nullptr;
75 std::function<std::nullptr_t ()>
get =
nullptr;
82 template <
typename keyT =
void>
86 static_assert(std::is_same_v<keyT, std::decay_t<keyT>>,
87 "InTerminalBase<keyT,valueT> assumes keyT is a non-decayable type");
112 template <
typename Key = keyT>
113 std::enable_if_t<!meta::is_void_v<Key>,
void>
set_size(
const Key &key, std::size_t
size) {
114 if (!
setsize_callback)
throw std::runtime_error(
"set_size callback not initialized");
118 template <
typename Key = keyT>
119 std::enable_if_t<meta::is_void_v<Key>,
void>
set_size(std::size_t
size) {
120 if (!
setsize_callback)
throw std::runtime_error(
"set_size callback not initialized");
124 template <
typename Key = keyT>
125 std::enable_if_t<!meta::is_void_v<Key>,
void>
finalize(
const Key &key) {
127 if (!
finalize_callback)
throw std::runtime_error(
"finalize callback not initialized");
131 template <
typename Key = keyT>
132 std::enable_if_t<meta::is_void_v<Key>,
void>
finalize() {
133 if (!
finalize_callback)
throw std::runtime_error(
"finalize callback not initialized");
143 template <
typename keyT =
void,
typename valueT =
void>
149 static_assert(std::is_same_v<keyT, std::decay_t<keyT>>,
"In<keyT,valueT> assumes keyT is a non-decayable type");
151 static_assert(std::is_same_v<std::remove_const_t<valueT>, std::decay_t<valueT>>,
152 "In<keyT,valueT> assumes std::remove_const<T> is a non-decayable type");
170 In(
In &&other) =
delete;
171 In(
const In &other) =
delete;
172 In &operator=(
const In &other) =
delete;
173 In &operator=(
const In &&other) =
delete;
176 throw "Edge: to connect terminals use out->connect(in) rather than in->connect(out)";
198 this->send_callback = send_callback;
199 this->move_callback = move_callback;
200 this->broadcast_callback = bcast_callback;
201 this->prepare_send_callback = prepare_send_callback;
205 template <
typename Key = keyT,
typename Value = valueT>
206 std::enable_if_t<meta::is_none_void_v<Key, Value>,
void>
207 send(
const Key &key, Value &&value) {
209 static_assert(!
meta::is_void_v<keyT>,
"ttg::send<>(key,value) sending to a terminal expecting void key; use ttg::sendv(value) instead");
210 static_assert(!
meta::is_void_v<valueT>,
"ttg::send<>(key,value) sending to a terminal expecting void value; use ttg::sendk(key) instead");
211 constexpr auto value_is_rvref = !std::is_reference_v<Value>;
212 if constexpr (value_is_rvref) {
213 if (!move_callback)
throw std::runtime_error(
"move callback not initialized");
214 move_callback(key, std::move(value));
216 if (!send_callback)
throw std::runtime_error(
"send callback not initialized");
217 send_callback(key, value);
221 template <
typename Key = keyT>
222 std::enable_if_t<!meta::is_void_v<Key>,
void>
sendk(
const Key &key) {
224 static_assert(!
meta::is_void_v<keyT>,
"ttg::sendk<>(key) sending to a terminal expecting void key; use ttg::send() instead");
225 static_assert(
meta::is_void_v<valueT>,
"ttg::sendk<>(key) sending to a terminal expecting nonvoid value; use ttg::send(key,value) instead");
226 if (!send_callback)
throw std::runtime_error(
"send callback not initialized");
230 template <
typename Value = valueT>
231 std::enable_if_t<!meta::is_void_v<Value>,
void>
sendv(
234 static_assert(
meta::is_void_v<keyT>,
"ttg::sendv<>(value) sending to a terminal expecting nonvoid key; use ttg::send(key, value) instead");
235 static_assert(!
meta::is_void_v<valueT>,
"ttg::sendv<>(value) sending to a terminal expecting void value; use ttg::send() instead");
236 constexpr auto value_is_rvref = !std::is_reference_v<Value>;
237 if constexpr (value_is_rvref) {
238 if (!move_callback)
throw std::runtime_error(
"move callback not initialized");
239 move_callback(std::move(value));
242 if (!send_callback)
throw std::runtime_error(
"send callback not initialized");
243 send_callback(value);
249 static_assert(
meta::is_void_v<keyT>,
"ttg::send<>() sending to a terminal expecting nonvoid key; use ttg::sendk<>(key) instead");
250 static_assert(
meta::is_void_v<valueT>,
"ttg::send<>() sending to a terminal expecting nonvoid value; use ttg::sendv<>(value) instead");
251 if (!send_callback)
throw std::runtime_error(
"send callback not initialized");
257 template <
typename rangeT,
typename Value>
258 std::enable_if_t<!meta::is_void_v<Value>,
void>
broadcast(
const rangeT &keylist,
const Value &value) {
259 if (broadcast_callback) {
261 broadcast_callback(ttg::span<const keyT>(&(*std::begin(keylist)), std::distance(std::begin(keylist), std::end(keylist))),
265 broadcast_callback(ttg::span<const keyT>(&keylist, 1), value);
269 for (
auto &&key : keylist)
send(key, value);
272 send(keylist, value);
277 template <
typename rangeT,
typename Value>
278 std::enable_if_t<!meta::is_void_v<Value>,
void>
broadcast(
const rangeT &keylist, Value &&value) {
279 const Value &v = value;
280 if (broadcast_callback) {
283 ttg::span<const keyT>(&(*std::begin(keylist)), std::distance(std::begin(keylist), std::end(keylist))), v);
286 broadcast_callback(ttg::span<const keyT>(&keylist, 1), v);
290 for (
auto &&key : keylist)
send(key, v);
293 send(ttg::span<const keyT>(&keylist, 1), v);
298 template <
typename rangeT,
typename Value = valueT>
299 std::enable_if_t<meta::is_void_v<Value>,
void>
broadcast(
const rangeT &keylist) {
300 if (broadcast_callback) {
303 ttg::span<const keyT>(&(*std::begin(keylist)), std::distance(std::begin(keylist), std::end(keylist))));
306 broadcast_callback(ttg::span<const keyT>(&keylist, 1));
310 for (
auto &&key : keylist)
sendk(key);
313 sendk(ttg::span<const keyT>(&keylist, 1));
319 template <
typename rangeT,
typename Value>
321 const std::remove_reference_t<Value> &v = value;
322 if (prepare_send_callback) {
324 prepare_send_callback(ttg::span<const keyT>(&(*std::begin(keylist)),
325 std::distance(std::begin(keylist), std::end(keylist))),
329 prepare_send_callback(ttg::span<const keyT>(&keylist, 1), v);
334 template <
typename Value>
336 const std::remove_reference_t<Value> &v = value;
337 if (prepare_send_callback) {
338 prepare_send_callback(v);
344 template <
typename keyT,
typename... valuesT>
346 using type = std::tuple<ttg::In<keyT, valuesT>...>;
349 template <
typename keyT,
typename... valuesT>
351 using type = std::tuple<ttg::In<keyT, valuesT>...>;
354 template <
typename keyT,
typename... valuesT>
360 template <
typename T>
362 template <
typename keyT>
364 template <
typename keyT,
typename valueT>
367 template <
typename T>
373 template <
typename keyT =
void>
377 static_assert(std::is_same_v<keyT, std::decay_t<keyT>>,
"Out<keyT,valueT> assumes keyT is a non-decayable type");
393 template <
typename Key = keyT>
394 std::enable_if_t<!meta::is_void_v<Key>,
void>
set_size(
const Key &key, std::size_t
size) {
401 template <
typename Key = keyT>
402 std::enable_if_t<meta::is_void_v<Key>,
void>
set_size(std::size_t
size) {
409 template <
typename Key = keyT>
410 std::enable_if_t<!meta::is_void_v<Key>,
void>
finalize(
const Key &key) {
417 template <
typename Key = keyT>
418 std::enable_if_t<meta::is_void_v<Key>,
void>
finalize() {
429 template <
typename keyT =
void,
typename valueT =
void>
434 static_assert(std::is_same_v<valueT, std::decay_t<valueT>>,
435 "Out<keyT,valueT> assumes valueT is a non-decayable type");
441 Out(
Out &&other) =
delete;
442 Out(
const Out &other) =
delete;
443 Out &operator=(
const Out &other) =
delete;
444 Out &operator=(
const Out &&other) =
delete;
454 if (!
dynamic_cast<input_terminal_type *
>(in))
455 throw std::invalid_argument(
456 std::string(
"you are trying to connect terminals with incompatible types:\ntype of this Terminal = ") +
457 detail::demangled_type_name(
this) +
"\ntype of other Terminal" + detail::demangled_type_name(in));
460 if (!
dynamic_cast<input_terminal_type *
>(in))
461 throw std::invalid_argument(
462 std::string(
"you are trying to connect terminals with incompatible types:\ntype of this Terminal = ") +
463 detail::demangled_type_name(
this) +
"\ntype of other Terminal" + detail::demangled_type_name(in));
465 throw std::invalid_argument(std::string(
"you are trying to connect an Out terminal to another Out terminal"));
475 template <
typename Key = keyT,
typename Value = valueT>
487 template <
typename Key = keyT,
typename Value = valueT>
492 for (std::size_t i = 0; i != N; ++i) {
498 read_successor->
sendv(value);
500 read_successor->sendv(std::forward<Value>(value));
502 if (
nullptr == move_successor) {
503 move_successor = successor;
509 if (
nullptr != move_successor) {
514 template <
typename Key = keyT,
typename Value = valueT>
515 std::enable_if_t<meta::is_all_void_v<Key, Value>,
void>
send() {
524 throw std::logic_error(
"Out<>: invalid successor type");
526 trace(
"Out<> ", this->
get_name(),
"(ptr=",
this,
") send to In<> ", successor->get_name(),
"(ptr=", successor,
531 template <
typename Key = keyT,
typename Value = valueT>
532 std::enable_if_t<meta::is_none_void_v<Key, Value>,
void>
533 send(
const Key &key, Value &&value) {
537 for (std::size_t i = 0; i != N; ++i) {
543 read_successor->
send(key, value);
545 read_successor->send(key, std::forward<Value>(value));
547 if (
nullptr == move_successor) {
548 move_successor = successor;
554 if (
nullptr != move_successor) {
561 template <
typename rangeT,
typename Key = keyT,
typename Value = valueT>
562 std::enable_if_t<meta::is_none_void_v<Key, Value>,
void>
broadcast(
const rangeT &keylist,
563 const Value &value) {
574 template <
typename rangeT,
typename Key = keyT>
586 template <
typename rangeT,
typename Key = keyT,
typename Value = valueT>
599 template <
typename Key = keyT,
typename Value = valueT>
615 template <
typename T>
617 template <
typename keyT>
619 template <
typename keyT,
typename valueT>
622 template <
typename T>
625 template <
typename T>
627 template <
typename...
Ts>
629 template <
typename...
Ts>
632 template <
typename T>
634 template <
typename T>
637 template <
typename T>
640 !std::is_const_v<std::remove_reference_t<T>>;
641 template <
typename T>
643 : std::bool_constant<is_nonconst_lvalue_reference_to_output_terminal_tuple_v<T>> {};
Edge is used to connect In and Out terminals.
typename base_type::finalize_callback_type finalize_callback_type
typename base_type::setsize_callback_type setsize_callback_type
std::enable_if_t<!meta::is_void_v< Key >, void > sendk(const Key &key)
void set_callback(const send_callback_type &send_callback, const move_callback_type &move_callback, const broadcast_callback_type &bcast_callback=broadcast_callback_type{}, const setsize_callback_type &setsize_callback=setsize_callback_type{}, const finalize_callback_type &finalize_callback=finalize_callback_type{}, const prepare_send_callback_type &prepare_send_callback=prepare_send_callback_type{})
In()
Default constructor of an Input Terminal.
static constexpr bool is_an_input_terminal
void prepare_send(const rangeT &keylist, Value &&value)
ttg::detail::ContainerWrapper< keyT, valueT > container
std::enable_if_t< meta::is_void_v< Value >, void > broadcast(const rangeT &keylist)
std::enable_if_t< meta::is_none_void_v< Key, Value >, void > send(const Key &key, Value &&value)
std::enable_if_t<!meta::is_void_v< Value >, void > broadcast(const rangeT &keylist, const Value &value)
std::enable_if_t<!meta::is_void_v< Value >, void > sendv(Value &&value)
meta::detail::send_callback_t< keyT, std::decay_t< valueT > > send_callback_type
std::enable_if_t<!meta::is_void_v< Value >, void > broadcast(const rangeT &keylist, Value &&value)
meta::detail::broadcast_callback_t< keyT, std::decay_t< valueT > > broadcast_callback_type
meta::detail::prepare_send_callback_t< keyT, std::decay_t< valueT > > prepare_send_callback_type
meta::detail::move_callback_t< keyT, std::decay_t< valueT > > move_callback_type
void prepare_send(Value &&value)
Base type for input terminals receiving messages annotated by task IDs of type keyT
std::enable_if_t< meta::is_void_v< Key >, void > finalize()
InTerminalBase(TerminalBase::Type t)
finalize_callback_type finalize_callback
setsize_callback_type setsize_callback
std::enable_if_t<!meta::is_void_v< Key >, void > finalize(const Key &key)
void set_callback(const setsize_callback_type &setsize_callback=setsize_callback_type{}, const finalize_callback_type &finalize_callback=finalize_callback_type{})
meta::detail::setsize_callback_t< keyT > setsize_callback_type
std::enable_if_t< meta::is_void_v< Key >, void > set_size(std::size_t size)
static constexpr bool is_an_input_terminal
std::enable_if_t<!meta::is_void_v< Key >, void > set_size(const Key &key, std::size_t size)
meta::detail::finalize_callback_t< keyT > finalize_callback_type
static constexpr bool is_an_output_terminal
void connect(TerminalBase *in) override
std::enable_if_t< meta::is_void_v< Key > &&!meta::is_void_v< Value >, void > sendv(Value &&value)
std::enable_if_t< meta::is_none_void_v< Key > &&!meta::is_void_v< valueT >, void > prepare_send(const rangeT &keylist, const Value &value)
std::enable_if_t< meta::is_void_v< Key > &&!meta::is_void_v< valueT >, void > prepare_send(const Value &value)
std::enable_if_t< meta::is_none_void_v< Key > &&meta::is_void_v< valueT >, void > broadcast(const rangeT &keylist)
std::enable_if_t< meta::is_none_void_v< Key, Value >, void > broadcast(const rangeT &keylist, const Value &value)
std::enable_if_t<!meta::is_void_v< Key > &&meta::is_void_v< Value >, void > sendk(const Key &key)
typename OutTerminalBase< keyT >::key_type key_type
std::enable_if_t< meta::is_none_void_v< Key, Value >, void > send(const Key &key, Value &&value)
std::enable_if_t< meta::is_all_void_v< Key, Value >, void > send()
static constexpr bool is_an_output_terminal
std::enable_if_t< meta::is_void_v< Key >, void > finalize()
std::enable_if_t< meta::is_void_v< Key >, void > set_size(std::size_t size)
const auto & successors() const
std::enable_if_t<!meta::is_void_v< Key >, void > set_size(const Key &key, std::size_t size)
std::enable_if_t<!meta::is_void_v< Key >, void > finalize(const Key &key)
void connect_base(TerminalBase *successor)
Type get_type() const
Returns the terminal type.
void connect_pull(TerminalBase *predecessor)
const std::vector< TerminalBase * > & get_connections() const
Get connections to successors.
const std::string & get_name() const
Returns name of terminal.
Type
describes the terminal type
@ Write
can only be written to
@ Read
can only be used to read immutable data
@ Consume
can only be used to read consumable data
A complete version of void.
typename input_terminals_tuple< keyT, valuesT... >::type input_terminals_tuple_t
top-level TTG namespace contains runtime-neutral functionality
int size(World world=default_execution_context())
int rank(World world=default_execution_context())
void trace(const T &t, const Ts &... ts)
ContainerWrapper()=default
std::function< size_t(keyT const &key)> owner
ContainerWrapper & operator=(const ContainerWrapper &)=default
ContainerWrapper(T &t, mapperT &&mapper, keymapT &&keymap)
ContainerWrapper(const ContainerWrapper &)=default
ContainerWrapper(ContainerWrapper &&)=default
std::function< valueT(keyT const &key)> get