Type matching ============= :cpp:class:`PureGadget`, :cpp:class:`ChannelGadget` as well as several other classes in Gadgetron have a template argument defining what type of data they accept. In the simplest case, this is simply a list of types. For instance .. code-block:: cpp ChannelGadget>> will match any message starting with a :cpp:class:`AcquisitionHeader` followed by a :cpp:class:`hoNDArray>`. If the message has more parts, these will simply be discarded. Also note that this is equivalent to .. code-block:: cpp ChannelGadget>>> Optional -------- If we want to include an element that will only appear some times, we can define it as optional. For instance, acquisitions can have a trajectory attached to them. This would look like .. code-block:: cpp ChannelGadget>, optional>> and in fact Types.h defines :cpp:class:`Acquisition` as .. code-block:: cpp using Acquisition = tuple>,optional>>; Variant ------- What if you need to create a ChannelGadget that accepts multiple types? For instance, one which receives both Acquisition and Waveform. In this case we can use a variant. .. code_block:: cpp ChannelGadget> In order to work with the data, you call :cpp:func:`Core::visit`, which is modelled from `std::visit `_. For instance, a toy example which counts the number of data points in all waveforms and acquisitions could look like .. code_block:: cpp void process(ChannelGadget& in, OutputChannel& out>){ for (auto acquisition_or_waveform : in){ size_t counts = 0; Core::visit( [counts&](auto& val){ auto& data = std::get<1>(val); //Data the second argument for both acquisitons and waveforms counts += data.size(); }, acquisition_or_waveform); } }