Overte C++ Documentation
Varying.h
1 //
2 // Varying.h
3 // render/src/task
4 //
5 // Created by Zach Pomerantz on 1/6/2016.
6 // Copyright 2016 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_task_Varying_h
13 #define hifi_task_Varying_h
14 
15 #include <type_traits>
16 #include <tuple>
17 #include <array>
18 
19 namespace task {
20 class Varying;
21 
22 
23 // A varying piece of data, to be used as Job/Task I/O
24 class Varying {
25 public:
26  Varying() {}
27  Varying(const Varying& var) : _concept(var._concept) {}
28  Varying& operator=(const Varying& var) {
29  _concept = var._concept;
30  return (*this);
31  }
32  template <class T> Varying(const T& data, const std::string& name = "noname") : _concept(std::make_shared<Model<T>>(data, name)) {}
33 
34  template <class T> bool canCast() const { return !!std::dynamic_pointer_cast<Model<T>>(_concept); }
35  template <class T> const T& get() const { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
36  template <class T> T& edit() { return std::static_pointer_cast<Model<T>>(_concept)->_data; }
37 
38  const std::string name() const { return _concept->name(); }
39 
40  // access potential sub varyings contained in this one.
41  Varying operator[] (uint8_t index) const { return (*_concept)[index]; }
42  uint8_t length() const { return (*_concept).length(); }
43 
44  template <class T> Varying getN (uint8_t index) const { return get<T>()[index]; }
45  template <class T> Varying editN (uint8_t index) { return edit<T>()[index]; }
46 
47  bool isNull() const { return _concept == nullptr; }
48 
49 protected:
50  class Concept {
51  public:
52  Concept(const std::string& name) : _name(name) {}
53 
54  virtual ~Concept() = default;
55 
56  virtual Varying operator[] (uint8_t index) const = 0;
57  virtual uint8_t length() const = 0;
58 
59  const std::string name() { return _name; }
60 
61  const std::string _name;
62  };
63  template <class T> class Model : public Concept {
64  public:
65  using Data = T;
66 
67  Model(const Data& data, const std::string& name) : Concept(name), _data(data) {}
68  virtual ~Model() = default;
69 
70  virtual Varying operator[] (uint8_t index) const override {
71  return Varying();
72  }
73  virtual uint8_t length() const override {
74  return 0;
75  }
76 
77  Data _data;
78  };
79 
80  std::shared_ptr<Concept> _concept;
81 };
82 
83 template < typename T0, typename T1 >
84 class VaryingSet2 : public std::pair<Varying, Varying> {
85 public:
86  using Parent = std::pair<Varying, Varying>;
87  typedef void is_proxy_tag;
88 
89  VaryingSet2() : Parent(Varying(T0()), Varying(T1())) {}
90  VaryingSet2(const VaryingSet2& pair) : Parent(pair.first, pair.second) {}
91  VaryingSet2(const Varying& first, const Varying& second) : Parent(first, second) {}
92 
93  const T0& get0() const { return first.get<T0>(); }
94  T0& edit0() { return first.edit<T0>(); }
95 
96  const T1& get1() const { return second.get<T1>(); }
97  T1& edit1() { return second.edit<T1>(); }
98 
99  virtual Varying operator[] (uint8_t index) const {
100  if (index == 1) {
101  return std::get<1>((*this));
102  } else {
103  return std::get<0>((*this));
104  }
105  }
106  virtual uint8_t length() const { return 2; }
107 
108  Varying asVarying() const { return Varying((*this)); }
109 };
110 
111 template <class T0, class T1, class T2>
112 class VaryingSet3 : public std::tuple<Varying, Varying,Varying>{
113 public:
114  using Parent = std::tuple<Varying, Varying, Varying>;
115 
116  VaryingSet3() : Parent(Varying(T0()), Varying(T1()), Varying(T2())) {}
117  VaryingSet3(const VaryingSet3& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src)) {}
118  VaryingSet3(const Varying& first, const Varying& second, const Varying& third) : Parent(first, second, third) {}
119 
120  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
121  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
122 
123  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
124  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
125 
126  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
127  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
128 
129  virtual Varying operator[] (uint8_t index) const {
130  if (index == 2) {
131  return std::get<2>((*this));
132  } else if (index == 1) {
133  return std::get<1>((*this));
134  } else {
135  return std::get<0>((*this));
136  }
137  }
138  virtual uint8_t length() const { return 3; }
139 
140  Varying asVarying() const { return Varying((*this)); }
141 };
142 
143 template <class T0, class T1, class T2, class T3>
144 class VaryingSet4 : public std::tuple<Varying, Varying, Varying, Varying>{
145 public:
146  using Parent = std::tuple<Varying, Varying, Varying, Varying>;
147 
148  VaryingSet4() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3())) {}
149  VaryingSet4(const VaryingSet4& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src)) {}
150  VaryingSet4(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth) : Parent(first, second, third, fourth) {}
151 
152  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
153  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
154 
155  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
156  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
157 
158  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
159  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
160 
161  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
162  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
163 
164  virtual Varying operator[] (uint8_t index) const {
165  if (index == 3) {
166  return std::get<3>((*this));
167  } else if (index == 2) {
168  return std::get<2>((*this));
169  } else if (index == 1) {
170  return std::get<1>((*this));
171  } else {
172  return std::get<0>((*this));
173  }
174  }
175  virtual uint8_t length() const { return 4; }
176 
177  Varying asVarying() const { return Varying((*this)); }
178 };
179 
180 template <class T0, class T1, class T2, class T3, class T4>
181 class VaryingSet5 : public std::tuple<Varying, Varying, Varying, Varying, Varying>{
182 public:
183  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying>;
184 
185  VaryingSet5() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4())) {}
186  VaryingSet5(const VaryingSet5& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src)) {}
187  VaryingSet5(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth) : Parent(first, second, third, fourth, fifth) {}
188 
189  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
190  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
191 
192  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
193  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
194 
195  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
196  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
197 
198  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
199  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
200 
201  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
202  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
203 
204  virtual Varying operator[] (uint8_t index) const {
205  if (index == 4) {
206  return std::get<4>((*this));
207  } else if (index == 3) {
208  return std::get<3>((*this));
209  } else if (index == 2) {
210  return std::get<2>((*this));
211  } else if (index == 1) {
212  return std::get<1>((*this));
213  } else {
214  return std::get<0>((*this));
215  }
216  }
217  virtual uint8_t length() const { return 5; }
218 
219  Varying asVarying() const { return Varying((*this)); }
220 };
221 
222 template <class T0, class T1, class T2, class T3, class T4, class T5>
223 class VaryingSet6 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying>{
224 public:
225  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying>;
226 
227  VaryingSet6() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5())) {}
228  VaryingSet6(const VaryingSet6& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src)) {}
229  VaryingSet6(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth) : Parent(first, second, third, fourth, fifth, sixth) {}
230 
231  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
232  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
233 
234  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
235  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
236 
237  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
238  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
239 
240  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
241  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
242 
243  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
244  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
245 
246  const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
247  T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
248 
249  virtual Varying operator[] (uint8_t index) const {
250  switch (index) {
251  default:
252  return std::get<0>((*this));
253  case 1:
254  return std::get<1>((*this));
255  case 2:
256  return std::get<2>((*this));
257  case 3:
258  return std::get<3>((*this));
259  case 4:
260  return std::get<4>((*this));
261  case 5:
262  return std::get<5>((*this));
263  };
264  }
265  virtual uint8_t length() const { return 6; }
266 
267  Varying asVarying() const { return Varying((*this)); }
268 };
269 
270 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
271 class VaryingSet7 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying>{
272 public:
273  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
274 
275  VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {}
276  VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {}
277  VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {}
278 
279  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
280  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
281 
282  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
283  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
284 
285  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
286  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
287 
288  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
289  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
290 
291  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
292  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
293 
294  const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
295  T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
296 
297  const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
298  T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
299 
300  virtual Varying operator[] (uint8_t index) const {
301  switch (index) {
302  default:
303  return std::get<0>((*this));
304  case 1:
305  return std::get<1>((*this));
306  case 2:
307  return std::get<2>((*this));
308  case 3:
309  return std::get<3>((*this));
310  case 4:
311  return std::get<4>((*this));
312  case 5:
313  return std::get<5>((*this));
314  case 6:
315  return std::get<6>((*this));
316  };
317  }
318  virtual uint8_t length() const { return 7; }
319 
320  Varying asVarying() const { return Varying((*this)); }
321 };
322 
323 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
324 class VaryingSet8 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying> {
325 public:
326  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
327 
328  VaryingSet8() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7())) {}
329  VaryingSet8(const VaryingSet8& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src)) {}
330  VaryingSet8(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth) {}
331 
332  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
333  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
334 
335  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
336  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
337 
338  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
339  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
340 
341  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
342  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
343 
344  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
345  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
346 
347  const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
348  T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
349 
350  const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
351  T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
352 
353  const T7& get7() const { return std::get<7>((*this)).template get<T7>(); }
354  T7& edit7() { return std::get<7>((*this)).template edit<T7>(); }
355 
356  virtual Varying operator[] (uint8_t index) const {
357  switch (index) {
358  default:
359  return std::get<0>((*this));
360  case 1:
361  return std::get<1>((*this));
362  case 2:
363  return std::get<2>((*this));
364  case 3:
365  return std::get<3>((*this));
366  case 4:
367  return std::get<4>((*this));
368  case 5:
369  return std::get<5>((*this));
370  case 6:
371  return std::get<6>((*this));
372  case 7:
373  return std::get<7>((*this));
374  };
375  }
376  virtual uint8_t length() const { return 8; }
377 
378  Varying asVarying() const { return Varying((*this)); }
379 };
380 
381 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
382 class VaryingSet9 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying> {
383 public:
384  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
385 
386  VaryingSet9() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7()), Varying(T8())) {}
387  VaryingSet9(const VaryingSet9& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src), std::get<8>(src)) {}
388  VaryingSet9(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth, const Varying& nine) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth, nine) {}
389 
390  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
391  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
392 
393  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
394  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
395 
396  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
397  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
398 
399  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
400  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
401 
402  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
403  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
404 
405  const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
406  T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
407 
408  const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
409  T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
410 
411  const T7& get7() const { return std::get<7>((*this)).template get<T7>(); }
412  T7& edit7() { return std::get<7>((*this)).template edit<T7>(); }
413 
414  const T8& get8() const { return std::get<8>((*this)).template get<T8>(); }
415  T8& edit8() { return std::get<8>((*this)).template edit<T8>(); }
416  virtual Varying operator[] (uint8_t index) const {
417  switch (index) {
418  default:
419  return std::get<0>((*this));
420  case 1:
421  return std::get<1>((*this));
422  case 2:
423  return std::get<2>((*this));
424  case 3:
425  return std::get<3>((*this));
426  case 4:
427  return std::get<4>((*this));
428  case 5:
429  return std::get<5>((*this));
430  case 6:
431  return std::get<6>((*this));
432  case 7:
433  return std::get<7>((*this));
434  case 8:
435  return std::get<8>((*this));
436  };
437  }
438  virtual uint8_t length() const { return 9; }
439 
440  Varying asVarying() const { return Varying((*this)); }
441 };
442 
443 
444 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
445 class VaryingSet10 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying> {
446 public:
447  using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
448 
449  VaryingSet10() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7()), Varying(T8()), Varying(T9())) {}
450  VaryingSet10(const VaryingSet10& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src), std::get<8>(src), std::get<9>(src)) {}
451  VaryingSet10(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth, const Varying& nine, const Varying& ten) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth, nine, ten) {}
452 
453  const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
454  T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
455 
456  const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
457  T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
458 
459  const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
460  T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
461 
462  const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
463  T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
464 
465  const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
466  T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
467 
468  const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
469  T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
470 
471  const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
472  T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
473 
474  const T7& get7() const { return std::get<7>((*this)).template get<T7>(); }
475  T7& edit7() { return std::get<7>((*this)).template edit<T7>(); }
476 
477  const T8& get8() const { return std::get<8>((*this)).template get<T8>(); }
478  T8& edit8() { return std::get<8>((*this)).template edit<T8>(); }
479 
480  const T9& get9() const { return std::get<9>((*this)).template get<T9>(); }
481  T9& edit9() { return std::get<9>((*this)).template edit<T9>(); }
482 
483  virtual Varying operator[] (uint8_t index) const {
484  switch (index) {
485  default:
486  return std::get<0>((*this));
487  case 1:
488  return std::get<1>((*this));
489  case 2:
490  return std::get<2>((*this));
491  case 3:
492  return std::get<3>((*this));
493  case 4:
494  return std::get<4>((*this));
495  case 5:
496  return std::get<5>((*this));
497  case 6:
498  return std::get<6>((*this));
499  case 7:
500  return std::get<7>((*this));
501  case 8:
502  return std::get<8>((*this));
503  case 9:
504  return std::get<9>((*this));
505  };
506  }
507  virtual uint8_t length() const { return 10; }
508 
509  Varying asVarying() const { return Varying((*this)); }
510 };
511 
512 template < class T, int NUM >
513 class VaryingArray : public std::array<Varying, NUM> {
514 public:
515  VaryingArray() {
516  for (size_t i = 0; i < NUM; i++) {
517  (*this)[i] = Varying(T());
518  }
519  }
520 
521  VaryingArray(std::initializer_list<Varying> list) {
522  assert(list.size() == NUM);
523  std::copy(list.begin(), list.end(), std::array<Varying, NUM>::begin());
524  }
525 };
526 
527 }
528 
529 #endif // hifi_task_Varying_h
A generic 3D model displaying geometry loaded from a URL.
Definition: Model.h:84