VTK-m  2.0
ArrayPortalValueReference.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_internal_ArrayPortalValueReference_h
11 #define vtk_m_internal_ArrayPortalValueReference_h
12 
13 #include <vtkm/TypeTraits.h>
14 #include <vtkm/Types.h>
15 #include <vtkm/VecTraits.h>
16 
17 namespace vtkm
18 {
19 namespace internal
20 {
21 
22 namespace detail
23 {
24 
25 // TODO: VecTraits should just always be supported. See #589.
26 
27 template <typename Vec, typename = typename std::enable_if<vtkm::HasVecTraits<Vec>::value>::type>
28 VTKM_EXEC_CONT inline vtkm::IdComponent SafeGetNumberOfComponents(const Vec& vec)
29 {
31 }
32 
33 VTKM_EXEC_CONT inline vtkm::IdComponent SafeGetNumberOfComponents(...)
34 {
35  return 1;
36 }
37 
38 template <typename Vec, typename = typename std::enable_if<vtkm::HasVecTraits<Vec>::value>::type>
39 VTKM_EXEC_CONT inline typename vtkm::VecTraits<Vec>::ComponentType SafeGetComponent(
40  const Vec& vec,
41  vtkm::IdComponent index)
42 {
43  return vtkm::VecTraits<Vec>::GetComponent(vec, index);
44 }
45 
46 template <typename T, typename = typename std::enable_if<!vtkm::HasVecTraits<T>::value>::type>
47 VTKM_EXEC_CONT inline T SafeGetComponent(const T& value, vtkm::IdComponent index)
48 {
49  VTKM_ASSERT(index == 0);
50  return value;
51 }
52 
53 } // namespace detail
54 
70 template <typename ArrayPortalType>
71 struct ArrayPortalValueReference
72 {
73  using ValueType = typename ArrayPortalType::ValueType;
74 
77  ArrayPortalValueReference(const ArrayPortalType& portal, vtkm::Id index)
78  : Portal(portal)
79  , Index(index)
80  {
81  }
82 
85  ArrayPortalValueReference(const ArrayPortalValueReference& ref)
86  : Portal(ref.Portal)
87  , Index(ref.Index)
88  {
89  }
90 
93  ValueType Get() const { return this->Portal.Get(this->Index); }
94 
97  operator ValueType(void) const { return this->Get(); }
98 
99  // Declaring Set as const seems a little weird because we are changing the value. But remember
100  // that ArrayPortalReference is only a reference class. The reference itself does not change,
101  // just the thing that it is referencing. So declaring as const is correct and necessary so that
102  // you can set the value of a reference returned from a function (which is a right hand side
103  // value).
104 
107  void Set(ValueType&& value) const { this->Portal.Set(this->Index, std::move(value)); }
108 
111  void Set(const ValueType& value) const { this->Portal.Set(this->Index, value); }
112 
113  VTKM_CONT
114  void Swap(const ArrayPortalValueReference<ArrayPortalType>& rhs) const noexcept
115  {
116  //we need use the explicit type not a proxy temp object
117  //A proxy temp object would point to the same underlying data structure
118  //and would not hold the old value of *this once *this was set to rhs.
119  const ValueType aValue = *this;
120  *this = rhs;
121  rhs = aValue;
122  }
123 
124  // Declaring operator= as const seems a little weird because we are changing the value. But
125  // remember that ArrayPortalReference is only a reference class. The reference itself does not
126  // change, just the thing that it is referencing. So declaring as const is correct and necessary
127  // so that you can set the value of a reference returned from a function (which is a right hand
128  // side value).
129 
132  const ArrayPortalValueReference<ArrayPortalType>& operator=(ValueType&& value) const
133  {
134  this->Set(std::move(value));
135  return *this;
136  }
137 
140  const ArrayPortalValueReference<ArrayPortalType>& operator=(const ValueType& value) const
141  {
142  this->Set(value);
143  return *this;
144  }
145 
146  // This special overload of the operator= is to override the behavior of the default operator=
147  // (which has the wrong behavior) with behavior consistent with the other operator= methods.
148  // It is not declared const because the default operator= is not declared const. If you try
149  // to do this assignment with a const object, you will get one of the operator= above.
151  VTKM_EXEC_CONT ArrayPortalValueReference<ArrayPortalType>& operator=(
152  const ArrayPortalValueReference<ArrayPortalType>& rhs)
153  {
154  this->Set(static_cast<ValueType>(rhs.Portal.Get(rhs.Index)));
155  return *this;
156  }
157 
159  template <typename T>
160  VTKM_EXEC_CONT ValueType operator+=(const T& rhs) const
161  {
162  ValueType lhs = this->Get();
163  lhs += rhs;
164  this->Set(lhs);
165  return lhs;
166  }
168  template <typename T>
169  VTKM_EXEC_CONT ValueType operator+=(const ArrayPortalValueReference<T>& rhs) const
170  {
171  ValueType lhs = this->Get();
172  lhs += rhs.Get();
173  this->Set(lhs);
174  return lhs;
175  }
176 
178  template <typename T>
179  VTKM_EXEC_CONT ValueType operator-=(const T& rhs) const
180  {
181  ValueType lhs = this->Get();
182  lhs -= rhs;
183  this->Set(lhs);
184  return lhs;
185  }
187  template <typename T>
188  VTKM_EXEC_CONT ValueType operator-=(const ArrayPortalValueReference<T>& rhs) const
189  {
190  ValueType lhs = this->Get();
191  lhs -= rhs.Get();
192  this->Set(lhs);
193  return lhs;
194  }
195 
197  template <typename T>
198  VTKM_EXEC_CONT ValueType operator*=(const T& rhs) const
199  {
200  ValueType lhs = this->Get();
201  lhs *= rhs;
202  this->Set(lhs);
203  return lhs;
204  }
206  template <typename T>
207  VTKM_EXEC_CONT ValueType operator*=(const ArrayPortalValueReference<T>& rhs) const
208  {
209  ValueType lhs = this->Get();
210  lhs *= rhs.Get();
211  this->Set(lhs);
212  return lhs;
213  }
214 
216  template <typename T>
217  VTKM_EXEC_CONT ValueType operator/=(const T& rhs) const
218  {
219  ValueType lhs = this->Get();
220  lhs /= rhs;
221  this->Set(lhs);
222  return lhs;
223  }
225  template <typename T>
226  VTKM_EXEC_CONT ValueType operator/=(const ArrayPortalValueReference<T>& rhs) const
227  {
228  ValueType lhs = this->Get();
229  lhs /= rhs.Get();
230  this->Set(lhs);
231  return lhs;
232  }
233 
235  template <typename T>
236  VTKM_EXEC_CONT ValueType operator%=(const T& rhs) const
237  {
238  ValueType lhs = this->Get();
239  lhs %= rhs;
240  this->Set(lhs);
241  return lhs;
242  }
244  template <typename T>
245  VTKM_EXEC_CONT ValueType operator%=(const ArrayPortalValueReference<T>& rhs) const
246  {
247  ValueType lhs = this->Get();
248  lhs %= rhs.Get();
249  this->Set(lhs);
250  return lhs;
251  }
252 
254  template <typename T>
255  VTKM_EXEC_CONT ValueType operator&=(const T& rhs) const
256  {
257  ValueType lhs = this->Get();
258  lhs &= rhs;
259  this->Set(lhs);
260  return lhs;
261  }
263  template <typename T>
264  VTKM_EXEC_CONT ValueType operator&=(const ArrayPortalValueReference<T>& rhs) const
265  {
266  ValueType lhs = this->Get();
267  lhs &= rhs.Get();
268  this->Set(lhs);
269  return lhs;
270  }
271 
273  template <typename T>
274  VTKM_EXEC_CONT ValueType operator|=(const T& rhs) const
275  {
276  ValueType lhs = this->Get();
277  lhs |= rhs;
278  this->Set(lhs);
279  return lhs;
280  }
282  template <typename T>
283  VTKM_EXEC_CONT ValueType operator|=(const ArrayPortalValueReference<T>& rhs) const
284  {
285  ValueType lhs = this->Get();
286  lhs |= rhs.Get();
287  this->Set(lhs);
288  return lhs;
289  }
290 
292  template <typename T>
293  VTKM_EXEC_CONT ValueType operator^=(const T& rhs) const
294  {
295  ValueType lhs = this->Get();
296  lhs ^= rhs;
297  this->Set(lhs);
298  return lhs;
299  }
301  template <typename T>
302  VTKM_EXEC_CONT ValueType operator^=(const ArrayPortalValueReference<T>& rhs) const
303  {
304  ValueType lhs = this->Get();
305  lhs ^= rhs.Get();
306  this->Set(lhs);
307  return lhs;
308  }
309 
311  template <typename T>
312  VTKM_EXEC_CONT ValueType operator>>=(const T& rhs) const
313  {
314  ValueType lhs = this->Get();
315  lhs >>= rhs;
316  this->Set(lhs);
317  return lhs;
318  }
320  template <typename T>
321  VTKM_EXEC_CONT ValueType operator>>=(const ArrayPortalValueReference<T>& rhs) const
322  {
323  ValueType lhs = this->Get();
324  lhs >>= rhs.Get();
325  this->Set(lhs);
326  return lhs;
327  }
328 
330  template <typename T>
331  VTKM_EXEC_CONT ValueType operator<<=(const T& rhs) const
332  {
333  ValueType lhs = this->Get();
334  lhs <<= rhs;
335  this->Set(lhs);
336  return lhs;
337  }
339  template <typename T>
340  VTKM_EXEC_CONT ValueType operator<<=(const ArrayPortalValueReference<T>& rhs) const
341  {
342  ValueType lhs = this->Get();
343  lhs <<= rhs.Get();
344  this->Set(lhs);
345  return lhs;
346  }
347 
348  // Support Vec operations so that the reference can be treated as such Vec objects. Note
349  // that although the [] operator is supported, you can only read components this way. You
350  // cannot write components one at a time.
351  VTKM_EXEC_CONT vtkm::IdComponent GetNumberOfComponents() const
352  {
353  return detail::SafeGetNumberOfComponents(static_cast<ValueType>(*this));
354  }
355  VTKM_EXEC_CONT auto operator[](vtkm::IdComponent index) const
356  -> decltype(detail::SafeGetComponent(std::declval<ValueType>(), index))
357  {
358  return detail::SafeGetComponent(static_cast<ValueType>(*this), index);
359  }
360 
361 private:
362  const ArrayPortalType& Portal;
363  vtkm::Id Index;
364 };
365 
366 //implement a custom swap function, since the std::swap won't work
367 //since we return RValues instead of Lvalues
368 template <typename T>
369 void swap(const vtkm::internal::ArrayPortalValueReference<T>& a,
370  const vtkm::internal::ArrayPortalValueReference<T>& b)
371 {
372  a.Swap(b);
373 }
374 
375 template <typename T>
376 void swap(const vtkm::internal::ArrayPortalValueReference<T>& a,
377  typename vtkm::internal::ArrayPortalValueReference<T>::ValueType& b)
378 {
379  using ValueType = typename vtkm::internal::ArrayPortalValueReference<T>::ValueType;
380  const ValueType tmp = a;
381  a = b;
382  b = tmp;
383 }
384 
385 template <typename T>
386 void swap(typename vtkm::internal::ArrayPortalValueReference<T>::ValueType& a,
387  const vtkm::internal::ArrayPortalValueReference<T>& b)
388 {
389  using ValueType = typename vtkm::internal::ArrayPortalValueReference<T>::ValueType;
390  const ValueType tmp = b;
391  b = a;
392  a = tmp;
393 }
394 
395 // The reason why all the operators on ArrayPortalValueReference are defined outside of the class
396 // is so that in the case that the operator in question is not defined in the value type, these
397 // operators will not be instantiated (and therefore cause a compile error) unless they are
398 // directly used (in which case a compile error is appropriate).
399 
401 template <typename LhsPortalType>
402 VTKM_EXEC_CONT auto operator==(const ArrayPortalValueReference<LhsPortalType>& lhs,
403  const typename LhsPortalType::ValueType& rhs)
404  -> decltype(lhs.Get() == rhs)
405 {
406  return lhs.Get() == rhs;
407 }
409 template <typename LhsPortalType, typename RhsPortalType>
410 VTKM_EXEC_CONT auto operator==(const ArrayPortalValueReference<LhsPortalType>& lhs,
411  const ArrayPortalValueReference<RhsPortalType>& rhs)
412  -> decltype(lhs.Get() == rhs.Get())
413 {
414  return lhs.Get() == rhs.Get();
415 }
417 template <typename RhsPortalType>
418 VTKM_EXEC_CONT auto operator==(const typename RhsPortalType::ValueType& lhs,
419  const ArrayPortalValueReference<RhsPortalType>& rhs)
420  -> decltype(lhs == rhs.Get())
421 {
422  return lhs == rhs.Get();
423 }
424 
426 template <typename LhsPortalType>
427 VTKM_EXEC_CONT auto operator!=(const ArrayPortalValueReference<LhsPortalType>& lhs,
428  const typename LhsPortalType::ValueType& rhs)
429  -> decltype(lhs.Get() != rhs)
430 {
431  return lhs.Get() != rhs;
432 }
434 template <typename LhsPortalType, typename RhsPortalType>
435 VTKM_EXEC_CONT auto operator!=(const ArrayPortalValueReference<LhsPortalType>& lhs,
436  const ArrayPortalValueReference<RhsPortalType>& rhs)
437  -> decltype(lhs.Get() != rhs.Get())
438 {
439  return lhs.Get() != rhs.Get();
440 }
442 template <typename RhsPortalType>
443 VTKM_EXEC_CONT auto operator!=(const typename RhsPortalType::ValueType& lhs,
444  const ArrayPortalValueReference<RhsPortalType>& rhs)
445  -> decltype(lhs != rhs.Get())
446 {
447  return lhs != rhs.Get();
448 }
449 
451 template <typename LhsPortalType>
452 VTKM_EXEC_CONT auto operator<(const ArrayPortalValueReference<LhsPortalType>& lhs,
453  const typename LhsPortalType::ValueType& rhs)
454  -> decltype(lhs.Get() < rhs)
455 {
456  return lhs.Get() < rhs;
457 }
459 template <typename LhsPortalType, typename RhsPortalType>
460 VTKM_EXEC_CONT auto operator<(const ArrayPortalValueReference<LhsPortalType>& lhs,
461  const ArrayPortalValueReference<RhsPortalType>& rhs)
462  -> decltype(lhs.Get() < rhs.Get())
463 {
464  return lhs.Get() < rhs.Get();
465 }
467 template <typename RhsPortalType>
468 VTKM_EXEC_CONT auto operator<(const typename RhsPortalType::ValueType& lhs,
469  const ArrayPortalValueReference<RhsPortalType>& rhs)
470  -> decltype(lhs < rhs.Get())
471 {
472  return lhs < rhs.Get();
473 }
474 
476 template <typename LhsPortalType>
477 VTKM_EXEC_CONT auto operator>(const ArrayPortalValueReference<LhsPortalType>& lhs,
478  const typename LhsPortalType::ValueType& rhs)
479  -> decltype(lhs.Get() > rhs)
480 {
481  return lhs.Get() > rhs;
482 }
484 template <typename LhsPortalType, typename RhsPortalType>
485 VTKM_EXEC_CONT auto operator>(const ArrayPortalValueReference<LhsPortalType>& lhs,
486  const ArrayPortalValueReference<RhsPortalType>& rhs)
487  -> decltype(lhs.Get() > rhs.Get())
488 {
489  return lhs.Get() > rhs.Get();
490 }
492 template <typename RhsPortalType>
493 VTKM_EXEC_CONT auto operator>(const typename RhsPortalType::ValueType& lhs,
494  const ArrayPortalValueReference<RhsPortalType>& rhs)
495  -> decltype(lhs > rhs.Get())
496 {
497  return lhs > rhs.Get();
498 }
499 
501 template <typename LhsPortalType>
502 VTKM_EXEC_CONT auto operator<=(const ArrayPortalValueReference<LhsPortalType>& lhs,
503  const typename LhsPortalType::ValueType& rhs)
504  -> decltype(lhs.Get() <= rhs)
505 {
506  return lhs.Get() <= rhs;
507 }
509 template <typename LhsPortalType, typename RhsPortalType>
510 VTKM_EXEC_CONT auto operator<=(const ArrayPortalValueReference<LhsPortalType>& lhs,
511  const ArrayPortalValueReference<RhsPortalType>& rhs)
512  -> decltype(lhs.Get() <= rhs.Get())
513 {
514  return lhs.Get() <= rhs.Get();
515 }
517 template <typename RhsPortalType>
518 VTKM_EXEC_CONT auto operator<=(const typename RhsPortalType::ValueType& lhs,
519  const ArrayPortalValueReference<RhsPortalType>& rhs)
520  -> decltype(lhs <= rhs.Get())
521 {
522  return lhs <= rhs.Get();
523 }
524 
526 template <typename LhsPortalType>
527 VTKM_EXEC_CONT auto operator>=(const ArrayPortalValueReference<LhsPortalType>& lhs,
528  const typename LhsPortalType::ValueType& rhs)
529  -> decltype(lhs.Get() >= rhs)
530 {
531  return lhs.Get() >= rhs;
532 }
534 template <typename LhsPortalType, typename RhsPortalType>
535 VTKM_EXEC_CONT auto operator>=(const ArrayPortalValueReference<LhsPortalType>& lhs,
536  const ArrayPortalValueReference<RhsPortalType>& rhs)
537  -> decltype(lhs.Get() >= rhs.Get())
538 {
539  return lhs.Get() >= rhs.Get();
540 }
542 template <typename RhsPortalType>
543 VTKM_EXEC_CONT auto operator>=(const typename RhsPortalType::ValueType& lhs,
544  const ArrayPortalValueReference<RhsPortalType>& rhs)
545  -> decltype(lhs >= rhs.Get())
546 {
547  return lhs >= rhs.Get();
548 }
549 
551 template <typename LhsPortalType>
552 VTKM_EXEC_CONT auto operator+(const ArrayPortalValueReference<LhsPortalType>& lhs,
553  const typename LhsPortalType::ValueType& rhs)
554  -> decltype(lhs.Get() + rhs)
555 {
556  return lhs.Get() + rhs;
557 }
559 template <typename LhsPortalType, typename RhsPortalType>
560 VTKM_EXEC_CONT auto operator+(const ArrayPortalValueReference<LhsPortalType>& lhs,
561  const ArrayPortalValueReference<RhsPortalType>& rhs)
562  -> decltype(lhs.Get() + rhs.Get())
563 {
564  return lhs.Get() + rhs.Get();
565 }
567 template <typename RhsPortalType>
568 VTKM_EXEC_CONT auto operator+(const typename RhsPortalType::ValueType& lhs,
569  const ArrayPortalValueReference<RhsPortalType>& rhs)
570  -> decltype(lhs + rhs.Get())
571 {
572  return lhs + rhs.Get();
573 }
574 
576 template <typename LhsPortalType>
577 VTKM_EXEC_CONT auto operator-(const ArrayPortalValueReference<LhsPortalType>& lhs,
578  const typename LhsPortalType::ValueType& rhs)
579  -> decltype(lhs.Get() - rhs)
580 {
581  return lhs.Get() - rhs;
582 }
584 template <typename LhsPortalType, typename RhsPortalType>
585 VTKM_EXEC_CONT auto operator-(const ArrayPortalValueReference<LhsPortalType>& lhs,
586  const ArrayPortalValueReference<RhsPortalType>& rhs)
587  -> decltype(lhs.Get() - rhs.Get())
588 {
589  return lhs.Get() - rhs.Get();
590 }
592 template <typename RhsPortalType>
593 VTKM_EXEC_CONT auto operator-(const typename RhsPortalType::ValueType& lhs,
594  const ArrayPortalValueReference<RhsPortalType>& rhs)
595  -> decltype(lhs - rhs.Get())
596 {
597  return lhs - rhs.Get();
598 }
599 
601 template <typename LhsPortalType>
602 VTKM_EXEC_CONT auto operator*(const ArrayPortalValueReference<LhsPortalType>& lhs,
603  const typename LhsPortalType::ValueType& rhs)
604  -> decltype(lhs.Get() * rhs)
605 {
606  return lhs.Get() * rhs;
607 }
609 template <typename LhsPortalType, typename RhsPortalType>
610 VTKM_EXEC_CONT auto operator*(const ArrayPortalValueReference<LhsPortalType>& lhs,
611  const ArrayPortalValueReference<RhsPortalType>& rhs)
612  -> decltype(lhs.Get() * rhs.Get())
613 {
614  return lhs.Get() * rhs.Get();
615 }
617 template <typename RhsPortalType>
618 VTKM_EXEC_CONT auto operator*(const typename RhsPortalType::ValueType& lhs,
619  const ArrayPortalValueReference<RhsPortalType>& rhs)
620  -> decltype(lhs * rhs.Get())
621 {
622  return lhs * rhs.Get();
623 }
624 
626 template <typename LhsPortalType>
627 VTKM_EXEC_CONT auto operator/(const ArrayPortalValueReference<LhsPortalType>& lhs,
628  const typename LhsPortalType::ValueType& rhs)
629  -> decltype(lhs.Get() / rhs)
630 {
631  return lhs.Get() / rhs;
632 }
634 template <typename LhsPortalType, typename RhsPortalType>
635 VTKM_EXEC_CONT auto operator/(const ArrayPortalValueReference<LhsPortalType>& lhs,
636  const ArrayPortalValueReference<RhsPortalType>& rhs)
637  -> decltype(lhs.Get() / rhs.Get())
638 {
639  return lhs.Get() / rhs.Get();
640 }
642 template <typename RhsPortalType>
643 VTKM_EXEC_CONT auto operator/(const typename RhsPortalType::ValueType& lhs,
644  const ArrayPortalValueReference<RhsPortalType>& rhs)
645  -> decltype(lhs / rhs.Get())
646 {
647  return lhs / rhs.Get();
648 }
649 
651 template <typename LhsPortalType>
652 VTKM_EXEC_CONT auto operator%(const ArrayPortalValueReference<LhsPortalType>& lhs,
653  const typename LhsPortalType::ValueType& rhs)
654  -> decltype(lhs.Get() % rhs)
655 {
656  return lhs.Get() % rhs;
657 }
659 template <typename LhsPortalType, typename RhsPortalType>
660 VTKM_EXEC_CONT auto operator%(const ArrayPortalValueReference<LhsPortalType>& lhs,
661  const ArrayPortalValueReference<RhsPortalType>& rhs)
662  -> decltype(lhs.Get() % rhs.Get())
663 {
664  return lhs.Get() % rhs.Get();
665 }
667 template <typename RhsPortalType>
668 VTKM_EXEC_CONT auto operator%(const typename RhsPortalType::ValueType& lhs,
669  const ArrayPortalValueReference<RhsPortalType>& rhs)
670  -> decltype(lhs % rhs.Get())
671 {
672  return lhs % rhs.Get();
673 }
674 
676 template <typename LhsPortalType>
677 VTKM_EXEC_CONT auto operator^(const ArrayPortalValueReference<LhsPortalType>& lhs,
678  const typename LhsPortalType::ValueType& rhs)
679  -> decltype(lhs.Get() ^ rhs)
680 {
681  return lhs.Get() ^ rhs;
682 }
684 template <typename LhsPortalType, typename RhsPortalType>
685 VTKM_EXEC_CONT auto operator^(const ArrayPortalValueReference<LhsPortalType>& lhs,
686  const ArrayPortalValueReference<RhsPortalType>& rhs)
687  -> decltype(lhs.Get() ^ rhs.Get())
688 {
689  return lhs.Get() ^ rhs.Get();
690 }
692 template <typename RhsPortalType>
693 VTKM_EXEC_CONT auto operator^(const typename RhsPortalType::ValueType& lhs,
694  const ArrayPortalValueReference<RhsPortalType>& rhs)
695  -> decltype(lhs ^ rhs.Get())
696 {
697  return lhs ^ rhs.Get();
698 }
699 
701 template <typename LhsPortalType>
702 VTKM_EXEC_CONT auto operator|(const ArrayPortalValueReference<LhsPortalType>& lhs,
703  const typename LhsPortalType::ValueType& rhs)
704  -> decltype(lhs.Get() | rhs)
705 {
706  return lhs.Get() | rhs;
707 }
709 template <typename LhsPortalType, typename RhsPortalType>
710 VTKM_EXEC_CONT auto operator|(const ArrayPortalValueReference<LhsPortalType>& lhs,
711  const ArrayPortalValueReference<RhsPortalType>& rhs)
712  -> decltype(lhs.Get() | rhs.Get())
713 {
714  return lhs.Get() | rhs.Get();
715 }
717 template <typename RhsPortalType>
718 VTKM_EXEC_CONT auto operator|(const typename RhsPortalType::ValueType& lhs,
719  const ArrayPortalValueReference<RhsPortalType>& rhs)
720  -> decltype(lhs | rhs.Get())
721 {
722  return lhs | rhs.Get();
723 }
724 
726 template <typename LhsPortalType>
727 VTKM_EXEC_CONT auto operator&(const ArrayPortalValueReference<LhsPortalType>& lhs,
728  const typename LhsPortalType::ValueType& rhs)
729  -> decltype(lhs.Get() & rhs)
730 {
731  return lhs.Get() & rhs;
732 }
734 template <typename LhsPortalType, typename RhsPortalType>
735 VTKM_EXEC_CONT auto operator&(const ArrayPortalValueReference<LhsPortalType>& lhs,
736  const ArrayPortalValueReference<RhsPortalType>& rhs)
737  -> decltype(lhs.Get() & rhs.Get())
738 {
739  return lhs.Get() & rhs.Get();
740 }
742 template <typename RhsPortalType>
743 VTKM_EXEC_CONT auto operator&(const typename RhsPortalType::ValueType& lhs,
744  const ArrayPortalValueReference<RhsPortalType>& rhs)
745  -> decltype(lhs & rhs.Get())
746 {
747  return lhs & rhs.Get();
748 }
749 
751 template <typename LhsPortalType>
752 VTKM_EXEC_CONT auto operator<<(const ArrayPortalValueReference<LhsPortalType>& lhs,
753  const typename LhsPortalType::ValueType& rhs)
754  -> decltype(lhs.Get() << rhs)
755 {
756  return lhs.Get() << rhs;
757 }
759 template <typename LhsPortalType, typename RhsPortalType>
760 VTKM_EXEC_CONT auto operator<<(const ArrayPortalValueReference<LhsPortalType>& lhs,
761  const ArrayPortalValueReference<RhsPortalType>& rhs)
762  -> decltype(lhs.Get() << rhs.Get())
763 {
764  return lhs.Get() << rhs.Get();
765 }
767 template <typename RhsPortalType>
768 VTKM_EXEC_CONT auto operator<<(const typename RhsPortalType::ValueType& lhs,
769  const ArrayPortalValueReference<RhsPortalType>& rhs)
770  -> decltype(lhs << rhs.Get())
771 {
772  return lhs << rhs.Get();
773 }
774 
776 template <typename LhsPortalType>
777 VTKM_EXEC_CONT auto operator>>(const ArrayPortalValueReference<LhsPortalType>& lhs,
778  const typename LhsPortalType::ValueType& rhs)
779  -> decltype(lhs.Get() >> rhs)
780 {
781  return lhs.Get() >> rhs;
782 }
784 template <typename LhsPortalType, typename RhsPortalType>
785 VTKM_EXEC_CONT auto operator>>(const ArrayPortalValueReference<LhsPortalType>& lhs,
786  const ArrayPortalValueReference<RhsPortalType>& rhs)
787  -> decltype(lhs.Get() >> rhs.Get())
788 {
789  return lhs.Get() >> rhs.Get();
790 }
792 template <typename RhsPortalType>
793 VTKM_EXEC_CONT auto operator>>(const typename RhsPortalType::ValueType& lhs,
794  const ArrayPortalValueReference<RhsPortalType>& rhs)
795  -> decltype(lhs >> rhs.Get())
796 {
797  return lhs >> rhs.Get();
798 }
799 
801 template <typename PortalType>
802 VTKM_EXEC_CONT auto operator~(const ArrayPortalValueReference<PortalType>& ref)
803  -> decltype(~ref.Get())
804 {
805  return ~ref.Get();
806 }
807 
809 template <typename PortalType>
810 VTKM_EXEC_CONT auto operator!(const ArrayPortalValueReference<PortalType>& ref)
811  -> decltype(!ref.Get())
812 {
813  return !ref.Get();
814 }
815 
817 template <typename LhsPortalType>
818 VTKM_EXEC_CONT auto operator&&(const ArrayPortalValueReference<LhsPortalType>& lhs,
819  const typename LhsPortalType::ValueType& rhs)
820  -> decltype(lhs.Get() && rhs)
821 {
822  return lhs.Get() && rhs;
823 }
825 template <typename LhsPortalType, typename RhsPortalType>
826 VTKM_EXEC_CONT auto operator&&(const ArrayPortalValueReference<LhsPortalType>& lhs,
827  const ArrayPortalValueReference<RhsPortalType>& rhs)
828  -> decltype(lhs.Get() && rhs.Get())
829 {
830  return lhs.Get() && rhs.Get();
831 }
833 template <typename RhsPortalType>
834 VTKM_EXEC_CONT auto operator&&(const typename RhsPortalType::ValueType& lhs,
835  const ArrayPortalValueReference<RhsPortalType>& rhs)
836  -> decltype(lhs && rhs.Get())
837 {
838  return lhs && rhs.Get();
839 }
840 
842 template <typename LhsPortalType>
843 VTKM_EXEC_CONT auto operator||(const ArrayPortalValueReference<LhsPortalType>& lhs,
844  const typename LhsPortalType::ValueType& rhs)
845  -> decltype(lhs.Get() || rhs)
846 {
847  return lhs.Get() || rhs;
848 }
850 template <typename LhsPortalType, typename RhsPortalType>
851 VTKM_EXEC_CONT auto operator||(const ArrayPortalValueReference<LhsPortalType>& lhs,
852  const ArrayPortalValueReference<RhsPortalType>& rhs)
853  -> decltype(lhs.Get() || rhs.Get())
854 {
855  return lhs.Get() || rhs.Get();
856 }
858 template <typename RhsPortalType>
859 VTKM_EXEC_CONT auto operator||(const typename RhsPortalType::ValueType& lhs,
860  const ArrayPortalValueReference<RhsPortalType>& rhs)
861  -> decltype(lhs || rhs.Get())
862 {
863  return lhs || rhs.Get();
864 }
865 }
866 } // namespace vtkm::internal
867 
868 namespace vtkm
869 {
870 
871 // Make specialization for TypeTraits and VecTraits so that the reference
872 // behaves the same as the value.
873 
874 template <typename PortalType>
875 struct TypeTraits<vtkm::internal::ArrayPortalValueReference<PortalType>>
876  : vtkm::TypeTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
877 {
878 };
879 
880 template <typename PortalType>
881 struct VecTraits<vtkm::internal::ArrayPortalValueReference<PortalType>>
882  : vtkm::VecTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
883 {
884 };
885 
886 } // namespace vtkm
887 
888 #endif //vtk_m_internal_ArrayPortalValueReference_h
vtkm::Swap
VTKM_EXEC_CONT void Swap(T &a, T &b)
Performs a swap operation. Safe to call from cuda code.
Definition: Swap.h:59
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in VTKm (an...
Definition: TypeTraits.h:61
Types.h
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::operator/
VTKM_EXEC_CONT vtkm::Vec< T, Size > operator/(vtkm::Vec< T, Size > a, const vtkm::Vec< T, Size > &b)
Definition: VecOperators.h:371
vtkm::operator*
VTKM_EXEC_CONT vtkm::Vec< T, Size > operator*(vtkm::Vec< T, Size > a, const vtkm::Vec< T, Size > &b)
Definition: VecOperators.h:185
vtkm::Vec
class VTKM_ALWAYS_EXPORT Vec
Definition: Types.h:319
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::operator+
VTKM_EXEC_CONT vtkm::Vec< T, Size > operator+(vtkm::Vec< T, Size > a, const vtkm::Vec< T, Size > &b)
Definition: VecOperators.h:92
TypeTraits.h
vtkm::VecTraits::GetComponent
static const VTKM_EXEC_CONT ComponentType & GetComponent(const typename std::remove_const< VecType >::type &vector, vtkm::IdComponent component)
Returns the value in a given component of the vector.
vtkm::operator-
VTKM_EXEC_CONT std::enable_if<(std::is_floating_point< T >::value||std::is_signed< T >::value), vtkm::Vec< T, Size > >::type operator-(vtkm::Vec< T, Size > x)
Definition: VecOperators.h:41
Index
int Index
Definition: ChooseCudaDevice.h:87
vtkm::operator<<
VTKM_CONT std::ostream & operator<<(std::ostream &stream, const vtkm::Bounds &bounds)
Helper function for printing bounds during testing.
Definition: Bounds.h:237
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::operator==
VTKM_EXEC_CONT bool operator==(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:615
vtkm::operator!=
VTKM_EXEC_CONT bool operator!=(const vtkm::Matrix< T, NumRow, NumCol > &a, const vtkm::Matrix< T, NumRow, NumCol > &b)
Definition: Matrix.h:629
vtkm::VecTraits::ComponentType
typename VecType::ComponentType ComponentType
Type of the components in the vector.
Definition: VecTraits.h:73
vtkm::cont::operator|
InitializeOptions operator|(const InitializeOptions &lhs, const InitializeOptions &rhs)
Definition: Initialize.h:67
vtkm::VecTraits
The VecTraits class gives several static members that define how to use a given type as a vector.
Definition: VecTraits.h:66
vtkm::cont::operator&
InitializeOptions operator&(const InitializeOptions &lhs, const InitializeOptions &rhs)
Definition: Initialize.h:72
vtkm::worklet::contourtree_distributed::operator>>
std::istream & operator>>(std::istream &inStream, SupernodeOnSuperarc &node)
Definition: TreeCompiler.h:215
VTKM_SUPPRESS_EXEC_WARNINGS
#define VTKM_SUPPRESS_EXEC_WARNINGS
Definition: ExportMacros.h:53
vtkm::VecTraits::GetNumberOfComponents
static vtkm::IdComponent GetNumberOfComponents(const VecType &vec)
Number of components in the given vector.
VecTraits.h