DiaDes  0.1
DIAgnosis of Discrete-Event System
Dispatcher.hh
Go to the documentation of this file.
1 
8 #ifndef __DIADES__UTILS__DISPATCHER__HH
9 #define __DIADES__UTILS__DISPATCHER__HH
10 
11 
12 #include<stack>
13 #include<iostream>
14 #include<array>
15 
16 
17 
18 namespace Diades {
19  namespace Utils {
20 
21  using namespace std;
22 
23 
24 
48  template<long unsigned int Size>
49  class Dispatcher {
50  public:
54  using Array = std::array<unsigned, Size>;
55 
56 
61  Dispatcher(unsigned n) : _current(), _stack(), _n(n) {
62  }
63 
68  const Array & init() {
69  _current.fill(0);
70  if (_current.size() > 1) {
71  _stack.push({0, _n});
72  _stack.push({_n, 0});
73  _current[_stack.size() - 2] = _stack.top().first;
74  }
75  return _current;
76  }
77 
84  const Array & next() {
85  if (_stack.empty()) {
86  return _current;
87  } else {
88  if (!hasNext()) {
89  // this the case the current node is (_n,0) and associates _n tokens to _current[_current.size()-1]
90  // so the current configuration is the last one in the enumeration, there is no next
91  while (!_stack.empty()) {
92  _stack.pop();
93  }
94  _current.fill(0);
95  } else {
96 
97  // the current node is like this: (n1,n2) with at least n1 non-null
98  // as it contains the last non-null dispatch
99  // we move to a new configuration when we dispatch n1-1 at this level and 1 below
100  auto tempPair = _stack.top();
101  _current[_stack.size() - 2] = 0;
102  _stack.pop();
103  _stack.push({tempPair.first - 1, tempPair.second + 1});
104  if (_stack.size() == _current.size() + 1) {
105  // this new configuration is not working as we need to do more dispatching (tempPair.second+1)
106  // but we are already at the end of the array
107  // by construction of the enumeration, we need to pop back to a node (n1,n2) with n1 \= 0
108  // and branch again as above
109  _stack.pop();
110  while (_stack.top().first == 0) {
111  _stack.pop();
112  }
113  tempPair = _stack.top();
114  _stack.pop();
115  _stack.push({tempPair.first - 1, tempPair.second + 1});
116  }
117  _current[_stack.size() - 2] = _stack.top().first;
118  _stack.push({tempPair.second + 1, 0});
119  _current[_stack.size() - 2] = _stack.top().first;
120  }
121  }
122  return _current;
123  }
124 
129  bool hasNext() const {
130  return !(_stack.empty() || ((_stack.size() == _current.size() + 1) && (_stack.top().first == _n)));
131  }
132 
137  bool empty() const {
138  return _current.size() == 0;
139  }
140 
141 
146  unsigned nbElements() const
147  {
148  return _n;
149  }
150 
155  const long unsigned int size() const
156  {
157  return Size;
158  }
159 
160 
161  private:
175  std::stack< std::pair<unsigned, unsigned> > _stack;
176 
180  unsigned _n;
181  };
182 
183 
184  }
185 }
186 
187 
188 
189 #endif /* __DIADES__UTILS__DISPATCHER__HH */
190 
std::stack< std::pair< unsigned, unsigned > > _stack
Definition: Dispatcher.hh:175
STL namespace.
std::array< unsigned, Size > Array
Definition: Dispatcher.hh:54
Namespace of the Diades project.
unsigned nbElements() const
Definition: Dispatcher.hh:146
const Array & init()
Definition: Dispatcher.hh:68
const Array & next()
Definition: Dispatcher.hh:84
const long unsigned int size() const
Definition: Dispatcher.hh:155