mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
125 lines
4.1 KiB
C
125 lines
4.1 KiB
C
|
//============================================================================
|
||
|
// Copyright (c) Kitware, Inc.
|
||
|
// All rights reserved.
|
||
|
// See LICENSE.txt for details.
|
||
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
// PURPOSE. See the above copyright notice for more information.
|
||
|
//
|
||
|
// Copyright 2016 Sandia Corporation.
|
||
|
// Copyright 2016 UT-Battelle, LLC.
|
||
|
// Copyright 2016 Los Alamos National Security.
|
||
|
//
|
||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||
|
// the U.S. Government retains certain rights in this software.
|
||
|
//
|
||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||
|
// this software.
|
||
|
//============================================================================
|
||
|
#ifndef vtk_m_internal_ArrayPortalValueReference_h
|
||
|
#define vtk_m_internal_ArrayPortalValueReference_h
|
||
|
|
||
|
#include <vtkm/Types.h>
|
||
|
#include <vtkm/TypeTraits.h>
|
||
|
#include <vtkm/VecTraits.h>
|
||
|
|
||
|
namespace vtkm {
|
||
|
namespace internal {
|
||
|
|
||
|
/// \brief A value class for returning setable values of an ArrayPortal
|
||
|
///
|
||
|
/// \c ArrayPortal classes have a pair of \c Get and \c Set methods that
|
||
|
/// retreive and store values in the array. This is to make it easy to
|
||
|
/// implement the \c ArrayPortal even it is not really an array. However, there
|
||
|
/// are some cases where the code structure expects a reference to a value that
|
||
|
/// can be set. For example, the \c IteratorFromArrayPortal class must return
|
||
|
/// something from its * operator that behaves like a reference.
|
||
|
///
|
||
|
/// For cases of this nature \c ArrayPortalValueReference can be used. This
|
||
|
/// class is constructured with an \c ArrayPortal and an index into the array.
|
||
|
/// The object then behaves like a reference to the value in the array. If you
|
||
|
/// set this reference object to a new value, it will call \c Set on the
|
||
|
/// \c ArrayPortal to insert the value into the array.
|
||
|
///
|
||
|
template<typename ArrayPortalType>
|
||
|
struct ArrayPortalValueReference
|
||
|
{
|
||
|
using ValueType = typename ArrayPortalType::ValueType;
|
||
|
|
||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||
|
VTKM_EXEC_CONT
|
||
|
ArrayPortalValueReference(const ArrayPortalType &portal, vtkm::Id index)
|
||
|
: Portal(portal), Index(index) { }
|
||
|
|
||
|
VTKM_CONT
|
||
|
void Swap( ArrayPortalValueReference<ArrayPortalType> &rhs ) throw()
|
||
|
{
|
||
|
//we need use the explicit type not a proxy temp object
|
||
|
//A proxy temp object would point to the same underlying data structure
|
||
|
//and would not hold the old value of *this once *this was set to rhs.
|
||
|
const ValueType aValue = *this;
|
||
|
*this = rhs;
|
||
|
rhs = aValue;
|
||
|
}
|
||
|
|
||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||
|
VTKM_EXEC_CONT
|
||
|
ArrayPortalValueReference<ArrayPortalType> &operator=(
|
||
|
const ArrayPortalValueReference<ArrayPortalType> &rhs)
|
||
|
{
|
||
|
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||
|
VTKM_EXEC_CONT
|
||
|
ValueType operator=(const ValueType& value)
|
||
|
{
|
||
|
this->Portal.Set(this->Index, value);
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||
|
VTKM_EXEC_CONT
|
||
|
operator ValueType(void) const
|
||
|
{
|
||
|
return this->Portal.Get(this->Index);
|
||
|
}
|
||
|
|
||
|
const ArrayPortalType& Portal;
|
||
|
vtkm::Id Index;
|
||
|
};
|
||
|
|
||
|
|
||
|
//implement a custom swap function, since the std::swap won't work
|
||
|
//since we return RValues instead of Lvalues
|
||
|
template<typename T>
|
||
|
void swap( vtkm::internal::ArrayPortalValueReference<T> a,
|
||
|
vtkm::internal::ArrayPortalValueReference<T> b)
|
||
|
{
|
||
|
a.Swap(b);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
} // namespace vtkm::internal
|
||
|
|
||
|
namespace vtkm {
|
||
|
|
||
|
// Make specialization for TypeTraits and VecTraits so that the reference
|
||
|
// behaves the same as the value.
|
||
|
|
||
|
template<typename PortalType>
|
||
|
struct TypeTraits<vtkm::internal::ArrayPortalValueReference<PortalType> >
|
||
|
: vtkm::TypeTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
|
||
|
{ };
|
||
|
|
||
|
template<typename PortalType>
|
||
|
struct VecTraits<vtkm::internal::ArrayPortalValueReference<PortalType> >
|
||
|
: vtkm::VecTraits<typename vtkm::internal::ArrayPortalValueReference<PortalType>::ValueType>
|
||
|
{ };
|
||
|
|
||
|
} // namespace vtkm
|
||
|
|
||
|
#endif //vtk_m_internal_ArrayPortalValueReference_h
|