Faninout.h
Go to the documentation of this file.
1 #ifndef WIRECELL_FANINOUT
2 #define WIRECELL_FANINOUT
3 
4 #include <boost/signals2.hpp>
5 #include <deque>
6 #include <map>
7 
8 namespace WireCell {
9 
10  /** A fanout which takes in Data from a connected slot and buffers it
11  * into set of addressable queues.
12  */
13  template<typename Data, typename Address = int>
14  class Fanout {
15  public:
16  // The fanout is held as a map from address to queue
17  typedef Data result_type;
18  typedef Address address_type;
19  typedef std::deque<result_type> data_queue;
20  typedef std::map< int, data_queue > queue_map;
21 
22  // Our signal for providers of input data
23  typedef boost::signals2::signal<result_type ()> signal;
24  // The slot type our signal accepts
25  typedef typename signal::slot_type slot;
26 
27  // Connect a slot to our signal.
28  void connect(const slot& s) { m_signal.connect(s); }
29 
30  /// Register an address.
31  void address(const address_type& addr) {
32  m_fan[addr] = data_queue();
33  }
34 
35  /// Return a data from the given address. If the address has not
36  /// yet been registered it will be but any previously returned
37  /// data will not be seen.
38  result_type operator()(const address_type& addr) {
39  data_queue& dq = m_fan[addr];
40  if (!dq.size()) {
41  result_type dat = *m_signal();
42  for (auto it = m_fan.begin(); it != m_fan.end(); ++it) {
43  it->second.push_back(dat);
44  }
45  }
46  result_type dat = dq.front();
47  dq.pop_front();
48  return dat;
49  }
50 
51  private:
52  signal m_signal;
53  queue_map m_fan;
54  };
55 
56  /** If you have a slot to connect to a Fanout which doesn't
57  * inherently care about the address to which it is attached, use
58  * the AddressedShunt as a go-between.
59  */
60  template<typename Data, typename Address = int>
61  class Addresser {
62  public:
63  typedef Data value_type;
64  typedef Address address_type;
65 
66  // Our signal for providers of input data
67  typedef boost::signals2::signal<value_type (const address_type& addr)> signal;
68  // The slot type our signal accepts
69  typedef typename signal::slot_type slot;
70 
71  Addresser(const address_type& addr) : m_addr(addr) {}
72 
73  // Connect a slot to our signal.
74  void connect(const slot& s) { m_signal.connect(s); }
75 
76  // the shunt
77  value_type operator()() {
78  return *m_signal(m_addr);
79  }
80 
81  private:
82  Address m_addr;
83  signal m_signal;
84  };
85 
86 
87 
88  /** Fan-in concept is inherent in boost::signals2, but does
89  * require some "combiner" to enact whatever fan-in policy is
90  * desired. This most obvious one is one which synchronizes all
91  * input into a simple collection. A signal like this will return
92  * a vector of its inputs.
93  *
94  * // a generator returning one higher count each time called
95  * Counter c1(10),c2(20),c3(30);
96  *
97  * boost::signals2::signal< int (), Fanin< std::vector<int> > > sig;
98  * sig.connect(c1);
99  * sig.connect(c2);
100  * sig.connect(c3);
101  *
102  * sig(); // --> vector(10,20,30)
103  */
104  template<typename Collection>
105  struct Fanin {
106  // result_type required for boost::signals2 combiners
107  typedef Collection result_type;
108  //typedef typename Collection::value_type value_type;
109 
110  template<typename InputIterator>
111  result_type operator()(InputIterator first, InputIterator last) const {
112  result_type ret;
113  while (first != last) {
114  ret.push_back(*first);
115  ++first;
116  }
117  return ret;
118  }
119  };
120 
121 
122 }
123 
124 
125 #endif
result_type operator()(InputIterator first, InputIterator last) const
Definition: Faninout.h:111
signal::slot_type slot
Definition: Faninout.h:25
Address address_type
Definition: Faninout.h:18
Addresser(const address_type &addr)
Definition: Faninout.h:71
Address address_type
Definition: Faninout.h:64
std::deque< result_type > data_queue
Definition: Faninout.h:19
boost::signals2::signal< result_type()> signal
Definition: Faninout.h:23
Definition: Main.h:22
void address(const address_type &addr)
Register an address.
Definition: Faninout.h:31
void connect(const slot &s)
Definition: Faninout.h:74
signal m_signal
Definition: Faninout.h:52
signal::slot_type slot
Definition: Faninout.h:69
Collection result_type
Definition: Faninout.h:107
result_type operator()(const address_type &addr)
Definition: Faninout.h:38
boost::signals2::signal< value_type(const address_type &addr)> signal
Definition: Faninout.h:67
std::map< int, data_queue > queue_map
Definition: Faninout.h:20
constexpr std::enable_if_t< are_cv_compatible< TO, FROM >::value, std::add_pointer_t< std::remove_pointer_t< TO > > > addr(FROM &from)
Definition: ensurePointer.h:35
static QCString * s
Definition: config.cpp:1042
Data result_type
Definition: Faninout.h:17
value_type operator()()
Definition: Faninout.h:77
void connect(const slot &s)
Definition: Faninout.h:28
queue_map m_fan
Definition: Faninout.h:53