STADLS
visitors.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <array>
5 #include <iterator>
6 #include <stdexcept>
7 #include <utility>
8 
9 namespace stadls {
10 
19 template <typename T>
21 {
23 
24  template <typename CoordinateT, typename ContainerT>
25  auto operator()(CoordinateT const& coord, ContainerT const& container)
26  -> decltype(container.addresses(coord), void())
27  {
28  auto const read_addresses = container.addresses(coord);
29  addresses.insert(addresses.end(), read_addresses.begin(), read_addresses.end());
30  }
31 
32  template <typename CoordinateT, typename ContainerT>
33  auto operator()(CoordinateT const& coord, ContainerT const& container)
34  -> decltype(container.read_addresses(coord), void())
35  {
36  auto const read_addresses = container.read_addresses(coord);
37  addresses.insert(addresses.end(), read_addresses.begin(), read_addresses.end());
38  }
39 
40  template <typename CoordinateT, typename ContainerT>
41  auto operator()(CoordinateT const& coord, ContainerT const& container)
42  -> decltype(container.template addresses<typename T::value_type>(coord), void())
43  {
44  auto const read_addresses = container.template addresses<typename T::value_type>(coord);
45  addresses.insert(addresses.end(), read_addresses.begin(), read_addresses.end());
46  }
47 
48  template <typename CoordinateT, typename ContainerT>
49  auto operator()(CoordinateT const& coord, ContainerT const& container)
50  -> decltype(container.template read_addresses<typename T::value_type>(coord), void())
51  {
52  auto const read_addresses =
53  container.template read_addresses<typename T::value_type>(coord);
54  addresses.insert(addresses.end(), read_addresses.begin(), read_addresses.end());
55  }
56 
57  template <typename CoordinateT, typename ContainerT>
58  auto operator()(CoordinateT const&, ContainerT const&) ->
59  typename std::enable_if<!ContainerT::has_local_data::value>::type
60  {
61  /* do nothing */
62  }
63 };
64 
73 template <typename T>
75 {
77 
78  template <typename CoordinateT, typename ContainerT>
79  auto operator()(CoordinateT const& coord, ContainerT const& container)
80  -> decltype(container.addresses(coord), void())
81  {
82  auto const write_addresses = container.addresses(coord);
83  addresses.insert(addresses.end(), write_addresses.begin(), write_addresses.end());
84  }
85 
86  template <typename CoordinateT, typename ContainerT>
87  auto operator()(CoordinateT const& coord, ContainerT const& container)
88  -> decltype(container.write_addresses(coord), void())
89  {
90  auto const write_addresses = container.write_addresses(coord);
91  addresses.insert(addresses.end(), write_addresses.begin(), write_addresses.end());
92  }
93 
94  template <typename CoordinateT, typename ContainerT>
95  auto operator()(CoordinateT const& coord, ContainerT const& container)
96  -> decltype(container.template addresses<typename T::value_type>(coord), void())
97  {
98  auto const write_addresses = container.template addresses<typename T::value_type>(coord);
99  addresses.insert(addresses.end(), write_addresses.begin(), write_addresses.end());
100  }
101 
102  template <typename CoordinateT, typename ContainerT>
103  auto operator()(CoordinateT const& coord, ContainerT const& container)
104  -> decltype(container.template write_addresses<typename T::value_type>(coord), void())
105  {
106  auto const write_addresses =
107  container.template write_addresses<typename T::value_type>(coord);
108  addresses.insert(addresses.end(), write_addresses.begin(), write_addresses.end());
109  }
110 
111  template <typename CoordinateT, typename ContainerT>
112  auto operator()(CoordinateT const&, ContainerT const&) ->
113  typename std::enable_if<!ContainerT::has_local_data::value>::type
114  {
115  /* do nothing */
116  }
117 };
118 
130 template <typename T>
132 {
133  T m_data;
134  typedef typename T::value_type value_type;
135  typename T::const_iterator m_it;
136 
137 public:
138  DecodeVisitor(T data) : m_data(std::move(data)), m_it(m_data.cbegin()) {}
139 
140  template <typename CoordinateT, typename ContainerT>
141  auto operator()(CoordinateT const& coord, ContainerT& container)
142  -> decltype(&ContainerT::decode, void())
143  {
144  decode(coord, container, &ContainerT::decode);
145  }
146 
147  template <typename CoordinateT, typename ContainerT>
148  auto operator()(CoordinateT const& coord, ContainerT& container)
149  -> decltype(&ContainerT::template decode<value_type>, void())
150  {
151  decode(coord, container, &ContainerT::template decode<value_type>);
152  }
153 
154  template <typename CoordinateT, typename ContainerT>
155  auto operator()(CoordinateT const&, ContainerT const&) ->
156  typename std::enable_if<!ContainerT::has_local_data::value>::type
157  {
158  /* do nothing */
159  }
160 
161 private:
162  template <typename CoordinateT, typename ContainerT, typename DecodeContainerT, size_t N>
163  void decode(
164  CoordinateT const& coord,
165  ContainerT& container,
166  void (DecodeContainerT::*decode)(CoordinateT const&, std::array<value_type, N> const&))
167  {
168  (container.*decode)(coord, slice<N>());
169  }
170 
171  template <typename CoordinateT, typename ContainerT, typename DecodeContainerT, size_t N>
172  void decode(
173  CoordinateT const&,
174  ContainerT& container,
175  void (DecodeContainerT::*decode)(std::array<value_type, N> const&))
176  {
177  (container.*decode)(slice<N>());
178  }
179 
180  template <size_t N>
181  auto slice() -> std::array<value_type, N>
182  {
183  if (N > remaining())
184  throw std::runtime_error("end of buffer during decoding");
185 
186  std::array<value_type, N> buf;
187 
188  auto prev_it = m_it;
189  std::advance(m_it, N);
190  std::copy(prev_it, m_it, buf.begin());
191 
192  return buf;
193  }
194 
195  size_t remaining() const { return std::distance(m_it, m_data.cend()); }
196 };
197 
210 template <typename T>
212 {
213  T& m_data;
214  typedef typename T::value_type value_type;
215 
216 public:
217  EncodeVisitor(T& data) : m_data(data) {}
218 
219  template <typename CoordinateT, typename ContainerT>
220  auto operator()(CoordinateT const& coord, ContainerT const& container)
221  -> decltype(&ContainerT::encode, void())
222  {
223  encode(coord, container, &ContainerT::encode);
224  }
225 
226  template <typename CoordinateT, typename ContainerT>
227  auto operator()(CoordinateT const& coord, ContainerT const& container)
228  -> decltype(&ContainerT::template encode<value_type>, void())
229  {
230  encode(coord, container, &ContainerT::template encode<value_type>);
231  }
232 
233  template <typename CoordinateT, typename ContainerT>
234  auto operator()(CoordinateT const&, ContainerT const&) ->
235  typename std::enable_if<!ContainerT::has_local_data::value>::type
236  {
237  /* do nothing */
238  }
239 
240 private:
241  template <typename CoordinateT, typename ContainerT, size_t N>
242  void encode(
243  CoordinateT const& coord,
244  ContainerT const& container,
245  std::array<value_type, N> (ContainerT::*encode)(CoordinateT const&) const)
246  {
247  auto const words = (container.*encode)(coord);
248  m_data.insert(m_data.end(), words.begin(), words.end());
249  }
250 
251  template <typename CoordinateT, typename ContainerT, size_t N>
252  void encode(
253  CoordinateT const&,
254  ContainerT const& container,
255  std::array<value_type, N> (ContainerT::*encode)() const)
256  {
257  auto const words = (container.*encode)();
258  m_data.insert(m_data.end(), words.begin(), words.end());
259  }
260 
261  template <typename CoordinateT, typename ContainerT>
262  void encode(
263  CoordinateT const& coord,
264  ContainerT const& container,
265  decltype(container.template encode<value_type>(coord)) (ContainerT::*encode)(
266  CoordinateT const&) const)
267  {
268  auto const words = (container.*encode)(coord);
269  m_data.insert(m_data.end(), words.begin(), words.end());
270  }
271 
272  template <typename CoordinateT, typename ContainerT>
273  void encode(
274  CoordinateT const&,
275  ContainerT const& container,
276  decltype(container.template encode<value_type>()) (ContainerT::*encode)() const)
277  {
278  auto const words = (container.*encode)();
279  m_data.insert(m_data.end(), words.begin(), words.end());
280  }
281 };
282 
283 } // namespace stadls
Fill the visited containers by decoding the specified configuration data.
Definition: visitors.h:132
auto operator()(CoordinateT const &coord, ContainerT &container) -> decltype(&ContainerT::decode, void())
Definition: visitors.h:141
auto operator()(CoordinateT const &coord, ContainerT &container) -> decltype(&ContainerT::template decode< value_type >, void())
Definition: visitors.h:148
auto operator()(CoordinateT const &, ContainerT const &) -> typename std::enable_if<!ContainerT::has_local_data::value >::type
Definition: visitors.h:155
Extract hardware configuration data for the visited containers.
Definition: visitors.h:212
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(&ContainerT::template encode< value_type >, void())
Definition: visitors.h:227
EncodeVisitor(T &data)
Definition: visitors.h:217
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(&ContainerT::encode, void())
Definition: visitors.h:220
auto operator()(CoordinateT const &, ContainerT const &) -> typename std::enable_if<!ContainerT::has_local_data::value >::type
Definition: visitors.h:234
Definition: visitors.h:9
Extract addresses for reading from hardware for the visited containers.
Definition: visitors.h:21
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.addresses(coord), void())
Definition: visitors.h:25
auto operator()(CoordinateT const &, ContainerT const &) -> typename std::enable_if<!ContainerT::has_local_data::value >::type
Definition: visitors.h:58
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.read_addresses(coord), void())
Definition: visitors.h:33
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.template addresses< typename T::value_type >(coord), void())
Definition: visitors.h:41
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.template read_addresses< typename T::value_type >(coord), void())
Definition: visitors.h:49
Extract addresses for writing to hardware for the visited containers.
Definition: visitors.h:75
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.addresses(coord), void())
Definition: visitors.h:79
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.template write_addresses< typename T::value_type >(coord), void())
Definition: visitors.h:103
auto operator()(CoordinateT const &, ContainerT const &) -> typename std::enable_if<!ContainerT::has_local_data::value >::type
Definition: visitors.h:112
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.template addresses< typename T::value_type >(coord), void())
Definition: visitors.h:95
auto operator()(CoordinateT const &coord, ContainerT const &container) -> decltype(container.write_addresses(coord), void())
Definition: visitors.h:87