# or_node Template Class

## Summary

A node that broadcasts messages received at its input ports to all of its successors. Each input port pi is a `receiver<Ti>`. The messages are broadcast individually as they are received at each port. The output message type is a struct that contains an index number that identifies the port on which the message arrived and a tuple of the input types where the value is stored.

## Syntax

    template<typename InputTuple>
     class or_node;

## Header

    #define TBB_PREVIEW_GRAPH_NODES 1
     #include "tbb/flow_graph.h"

## Description

An or_node is a `graph_node` and `sender< or_node<InputTyple>::output_type >`. It contains a tuple of input ports, each of which is a `receiver<Ti>` for each of the `T0 .. TN in InputTuple`. It supports multiple input receivers with distinct types and broadcasts each received message to all of its successors. Unlike a `join_node`, each message is broadcast individually to all successors of the `or_node` as it arrives at an input port. The incoming messages are wrapped in a struct that contains the index of the port number on which the message arrived and a tuple of the input types where the received value is stored.

The function template `input_port` described in 6.19 simplifies the syntax for getting a reference to a specific input port.

Rejection of messages by successors of the `or_node` is handled using the protocol in the Message Passing Protocol, see link below. The input ports never reject incoming messages.

`InputTuple` must be a `std::tuple<T0,T1,...>` where each element is copy-constructible and assignable.

## Example

    #include<cstdio>
    #define TBB_PREVIEW_GRAPH_NODES 1
    #include "tbb/flow_graph.h"

    using namespace tbb::flow;

    int main() {
      graph g;
      function_node<int,int> f1( g, unlimited,
                                   [](const int &i) { return 2*i; } );
      function_node<float,float> f2( g, unlimited,
                                   [](const float &f) { return f/2; } );

      or_node< std::tuple<int,float> > my_or_type;
      my_or_type o(g);

      function_node< my_or_type::output_type >
        f3( g, unlimited,
            []( const my_or_type::output_type &v ) {
                if (v.indx == 0) {
                  printf("Received an int %d\n",
                         std::get<0>(v.result));
                } else {
                  printf("Received a float %f\n",
                         std::get<1>(v.result));
               }
            }
        );
      make_edge( f1, input_port<0>(o) );
      make_edge( f2, input_port<1>(o) );
      make_edge( o, f3 );

      f1.try_put( 3 );
      f2.try_put( 3 );
      g.wait_for_all();
      return 0;
     }

In the example above, three `function_node` objects are created: `f1` multiplies an int i by 2, `f2` divides a `float f` by 2, and `f3` prints the values from `f1` and `f2` as they arrive. The `or_node j` wraps the output of `f1` and `f2` and forwards each result to `f3`. This example is purely a syntactic demonstration since there is very little work in the nodes.

## Members

    namespace tbb {
    namespace flow {
      template<typename InputTuple>
      class or_node : public graph_node,
      public sender<impl-dependent-output-type > {
      public:
        typedef struct { size_t indx; InputTuple result; } output_type;
        typedef receiver<output_type> successor_type;
        implementation-dependent-tuple input_ports_tuple_type;

        or_node(graph &g);
        or_node(const or_node &src);
        input_ports_type &input_ports();
        bool register_successor( successor_type &r );
        bool remove_successor( successor_type &r );
        bool try_get( output_type &v );
        bool try_reserve( output_type & );
        bool try_release( );
        bool try_consume( );
      };
    }
    }

The following table provides additional information on the members of this template class.
Member | Description
--- | ---
or_node(graph &g) | Constructs an `or_node` that belongs to the `graph g`.
or_node( const or_node &src ) | Constructs an `or_node`. The list of predecessors, messages in the input ports, and successors are NOT copied.
input_ports_type& input_ports() | Returns: A `std::tuple` of receivers. Each element inherits from `tbb::receiver<T>` where T is the type of message expected at that input. Each tuple element can be used like any other `flow::receiver<T>`.
bool register_successor( successor_type & r ) | Adds `r` to the set of successors. Returns: `true`.
bool remove_successor( successor_type & r ) | Removes `r` from the set of successors. Returns: `true`.
bool try_get( output_type &v ) | An `or_node` contains no buffering and therefore does not support gets. Returns: `false`.
bool try_reserve( output_type & ) | An `or_node` contains no buffering and therefore cannot be reserved. Returns: `false`.
bool try_release( ) | An `or_node` contains no buffering and therefore cannot be reserved. Returns: `false`.
bool try_consume( ) | An `or_node` contains no buffering and therefore cannot be reserved. Returns: `false`.

Parent topic: Flow Graph

## See Also

Message Passing Protocol