Viskores  1.0
UnknownCellSet.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_UnknownCellSet_h
19 #define viskores_cont_UnknownCellSet_h
20 
22 #include <viskores/cont/CellSet.h>
24 
26 
27 #include <memory>
28 
29 namespace viskores
30 {
31 namespace cont
32 {
33 
34 // Forward declaration.
35 template <typename CellSetList>
36 class UncertainCellSet;
37 
56 class VISKORES_CONT_EXPORT UnknownCellSet
57 {
58  std::shared_ptr<viskores::cont::CellSet> Container;
59 
61  std::true_type viskoresNotUsed(isUnknownCellSet))
62  {
63  *this = cellSet;
64  }
65 
66  template <typename CellSetType>
67  void InitializeKnownOrUnknownCellSet(const CellSetType& cellSet,
68  std::false_type viskoresNotUsed(isUnknownCellSet))
69  {
70  VISKORES_IS_CELL_SET(CellSetType);
71  this->Container = std::shared_ptr<viskores::cont::CellSet>(new CellSetType(cellSet));
72  }
73 
74 public:
75  VISKORES_CONT UnknownCellSet() = default;
76 
77  template <typename CellSetType>
78  VISKORES_CONT UnknownCellSet(const CellSetType& cellSet)
79  {
80  this->InitializeKnownOrUnknownCellSet(
81  cellSet, typename std::is_base_of<UnknownCellSet, CellSetType>::type{});
82  }
83 
89  VISKORES_CONT bool IsValid() const { return static_cast<bool>(this->Container); }
90 
93  VISKORES_CONT viskores::cont::CellSet* GetCellSetBase() { return this->Container.get(); }
95  {
96  return this->Container.get();
97  }
98 
106  VISKORES_CONT UnknownCellSet NewInstance() const;
107 
112  VISKORES_CONT std::string GetCellSetName() const;
113 
116  template <typename CellSetType>
117  VISKORES_CONT bool IsType() const
118  {
119  return (dynamic_cast<const CellSetType*>(this->Container.get()) != nullptr);
120  }
121 
123  {
124  return this->Container ? this->Container->GetNumberOfCells() : 0;
125  }
127  {
128  return this->Container ? this->Container->GetNumberOfFaces() : 0;
129  }
131  {
132  return this->Container ? this->Container->GetNumberOfEdges() : 0;
133  }
135  {
136  return this->Container ? this->Container->GetNumberOfPoints() : 0;
137  }
138 
140  {
141  return this->GetCellSetBase()->GetCellShape(id);
142  }
144  {
145  return this->GetCellSetBase()->GetNumberOfPointsInCell(id);
146  }
148  {
149  return this->GetCellSetBase()->GetCellPointIds(id, ptids);
150  }
151 
152  VISKORES_CONT void DeepCopyFrom(const CellSet* src) { this->GetCellSetBase()->DeepCopy(src); }
153 
154  VISKORES_CONT void PrintSummary(std::ostream& os) const;
155 
157  {
158  if (this->Container)
159  {
160  this->Container->ReleaseResourcesExecution();
161  }
162  }
163 
171  template <typename CellSetType>
173  {
174  // TODO: Currently, these are the same. But in the future we expect to support
175  // special CellSet types that can convert back and forth such as multiplexed
176  // cell sets or a cell set that can hold structured grids of any dimension.
177  return this->IsType<CellSetType>();
178  }
179 
188  template <typename CellSetType>
189  VISKORES_CONT void AsCellSet(CellSetType& cellSet) const
190  {
191  VISKORES_IS_CELL_SET(CellSetType);
192  CellSetType* cellSetPointer = dynamic_cast<CellSetType*>(this->Container.get());
193  if (cellSetPointer == nullptr)
194  {
195  VISKORES_LOG_CAST_FAIL(*this, CellSetType);
196  throwFailedDynamicCast(this->GetCellSetName(), viskores::cont::TypeToString(cellSet));
197  }
198  VISKORES_LOG_CAST_SUCC(*this, *cellSetPointer);
199  cellSet = *cellSetPointer;
200  }
201 
202  template <typename CellSetType>
203  VISKORES_CONT CellSetType AsCellSet() const
204  {
205  CellSetType cellSet;
206  this->AsCellSet(cellSet);
207  return cellSet;
208  }
210 
218  // Defined in UncertainCellSet.h
219  template <typename CellSetList>
220  VISKORES_CONT viskores::cont::UncertainCellSet<CellSetList> ResetCellSetList(CellSetList) const;
221  template <typename CellSetList>
223 
233  template <typename CellSetList, typename Functor, typename... Args>
234  VISKORES_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const;
235 };
236 
237 //=============================================================================
238 // Free function casting helpers
239 // (Not sure if these should be deprecated.)
240 
243 template <typename CellSetType>
244 VISKORES_CONT inline bool IsType(const viskores::cont::UnknownCellSet& unknownCellSet)
245 {
246  return unknownCellSet.IsType<CellSetType>();
247 }
248 
253 template <typename CellSetType>
254 VISKORES_CONT inline CellSetType Cast(const viskores::cont::UnknownCellSet& unknownCellSet)
255 {
256  return unknownCellSet.AsCellSet<CellSetType>();
257 }
258 
259 namespace internal
260 {
261 
262 VISKORES_CONT_EXPORT void ThrowCastAndCallException(const viskores::cont::UnknownCellSet&,
263  const std::type_info&);
264 
265 template <>
266 struct DynamicTransformTraits<viskores::cont::UnknownCellSet>
267 {
268  using DynamicTag = viskores::cont::internal::DynamicTransformTagCastAndCall;
269 };
270 
271 } // namespace internal
272 
273 template <typename CellSetList, typename Functor, typename... Args>
274 VISKORES_CONT void UnknownCellSet::CastAndCallForTypes(Functor&& functor, Args&&... args) const
275 {
276  VISKORES_IS_LIST(CellSetList);
277  bool called = false;
279  [&](auto cellSet)
280  {
281  if (!called && this->CanConvert<decltype(cellSet)>())
282  {
283  called = true;
284  this->AsCellSet(cellSet);
285  VISKORES_LOG_CAST_SUCC(*this, cellSet);
286 
287  // If you get a compile error here, it means that you have called CastAndCall for a
288  // viskores::cont::UnknownCellSet and the arguments of the functor do not match those
289  // being passed. This is often because it is calling the functor with a CellSet
290  // type that was not expected. Either add overloads to the functor to accept all
291  // possible cell set types or constrain the types tried for the CastAndCall.
292  functor(cellSet, args...);
293  }
294  },
295  CellSetList{});
296 
297  if (!called)
298  {
299  VISKORES_LOG_CAST_FAIL(*this, CellSetList);
300  internal::ThrowCastAndCallException(*this, typeid(CellSetList));
301  }
302 }
303 
306 template <typename Functor, typename... Args>
307 void CastAndCall(const viskores::cont::UnknownCellSet& cellSet, Functor&& f, Args&&... args)
308 {
309  cellSet.CastAndCallForTypes<VISKORES_DEFAULT_CELL_SET_LIST>(std::forward<Functor>(f),
310  std::forward<Args>(args)...);
311 }
312 
313 namespace internal
314 {
315 
319 template <typename T>
320 using UnknownCellSetCheck = typename std::is_base_of<viskores::cont::UnknownCellSet, T>::type;
321 
322 #define VISKORES_IS_UNKNOWN_CELL_SET(T) \
323  VISKORES_STATIC_ASSERT(::viskores::cont::internal::UnknownCellSetCheck<T>::value)
324 
325 #define VISKORES_IS_KNOWN_OR_UNKNOWN_CELL_SET(T) \
326  VISKORES_STATIC_ASSERT(::viskores::cont::internal::CellSetCheck<T>::type::value || \
327  ::viskores::cont::internal::UnknownCellSetCheck<T>::value)
328 
329 } // namespace internal
330 
331 } // namespace viskores::cont
332 } // namespace viskores
333 
334 //=============================================================================
335 // Specializations of serialization related classes
337 
338 namespace viskores
339 {
340 namespace cont
341 {
342 
343 template <>
344 struct VISKORES_CONT_EXPORT SerializableTypeString<viskores::cont::UnknownCellSet>
345 {
346  static VISKORES_CONT std::string Get();
347 };
348 }
349 } // namespace viskores::cont
350 
351 namespace mangled_diy_namespace
352 {
353 
354 template <>
355 struct VISKORES_CONT_EXPORT Serialization<viskores::cont::UnknownCellSet>
356 {
357 public:
358  static VISKORES_CONT void save(BinaryBuffer& bb, const viskores::cont::UnknownCellSet& obj);
359  static VISKORES_CONT void load(BinaryBuffer& bb, viskores::cont::UnknownCellSet& obj);
360 };
361 
362 } // namespace mangled_diy_namespace
363 
365 
366 // Include the implementation of UncertainCellSet. This should be included because there
367 // are methods in UnknownCellSet that produce objects of this type. It has to be included
368 // at the end to resolve the circular dependency.
370 
371 #endif //viskores_cont_UnknownCellSet_h
viskores::exec::arg::load
T load(const U &u, viskores::Id v)
Definition: FetchTagArrayDirectIn.h:44
viskores::cont::UnknownCellSet::InitializeKnownOrUnknownCellSet
void InitializeKnownOrUnknownCellSet(const CellSetType &cellSet, std::false_type)
Definition: UnknownCellSet.h:67
viskores::cont::UnknownCellSet::IsType
bool IsType() const
Returns true if this cell set matches the CellSetType template argument.
Definition: UnknownCellSet.h:117
viskores::cont::UnknownCellSet::GetNumberOfEdges
viskores::Id GetNumberOfEdges() const
Definition: UnknownCellSet.h:130
viskores::cont::CastAndCall
void CastAndCall(const DynamicObject &dynamicObject, Functor &&f, Args &&... args)
A Generic interface to CastAndCall.
Definition: CastAndCall.h:55
VISKORES_LOG_CAST_FAIL
#define VISKORES_LOG_CAST_FAIL(inObj, outType)
Convenience macro for logging a failed cast of dynamic object.
Definition: Logging.h:241
viskores::cont::UnknownCellSet::GetCellSetBase
viskores::cont::CellSet * GetCellSetBase()
Returns a pointer to the CellSet base class.
Definition: UnknownCellSet.h:93
viskores::cont::UnknownCellSet::UnknownCellSet
UnknownCellSet(const CellSetType &cellSet)
Definition: UnknownCellSet.h:78
viskoresNotUsed
#define viskoresNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:136
viskores::cont::UnknownCellSet::CastAndCallForTypes
void CastAndCallForTypes(Functor &&functor, Args &&... args) const
Call a functor using the underlying cell set type.
Definition: UnknownCellSet.h:274
viskores::cont::UnknownCellSet::DeepCopyFrom
void DeepCopyFrom(const CellSet *src)
Definition: UnknownCellSet.h:152
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
DefaultTypes.h
UncertainCellSet.h
mangled_diy_namespace
Definition: Particle.h:373
viskores::cont::UnknownCellSet::GetCellShape
viskores::UInt8 GetCellShape(viskores::Id id) const
Definition: UnknownCellSet.h:139
viskores::cont::IsType
bool IsType(const viskores::cont::UnknownArrayHandle &array)
Returns true if variant matches the type of ArrayHandleType.
Definition: UnknownArrayHandle.h:1272
viskores::cont::UnknownCellSet::Container
std::shared_ptr< viskores::cont::CellSet > Container
Definition: UnknownCellSet.h:58
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores::cont::UnknownCellSet::IsValid
bool IsValid() const
Returns whether a cell set is stored in this UnknownCellSet.
Definition: UnknownCellSet.h:89
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
VISKORES_DEFAULT_CELL_SET_LIST
#define VISKORES_DEFAULT_CELL_SET_LIST
Definition: DefaultTypes.h:85
CastAndCall.h
viskores::cont::UnknownCellSet::GetNumberOfPointsInCell
viskores::IdComponent GetNumberOfPointsInCell(viskores::Id id) const
Definition: UnknownCellSet.h:143
CellSet.h
viskores::cont::throwFailedDynamicCast
void throwFailedDynamicCast(const std::string &baseType, const std::string &derivedType)
Throws an ErrorBadType exception with the following message: Cast failed: baseType --> derivedType".
viskores::cont::UnknownCellSet::AsCellSet
CellSetType AsCellSet() const
Get the cell set as a known type.
Definition: UnknownCellSet.h:203
viskores::cont::UnknownCellSet::GetNumberOfCells
viskores::Id GetNumberOfCells() const
Definition: UnknownCellSet.h:122
viskores::cont::UnknownCellSet::GetNumberOfPoints
viskores::Id GetNumberOfPoints() const
Definition: UnknownCellSet.h:134
viskores::cont::UnknownCellSet::ReleaseResourcesExecution
void ReleaseResourcesExecution()
Definition: UnknownCellSet.h:156
viskores::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:177
viskores::cont::UnknownCellSet::GetCellSetBase
const viskores::cont::CellSet * GetCellSetBase() const
Definition: UnknownCellSet.h:94
viskores::cont::UnknownCellSet::CanConvert
bool CanConvert() const
Returns true if this cell set can be retrieved as the given type.
Definition: UnknownCellSet.h:172
viskores::cont::Cast
ArrayHandleType Cast(const viskores::cont::UnknownArrayHandle &array)
Returns variant cast to the given ArrayHandle type.
Definition: UnknownArrayHandle.h:1282
viskores::cont::UnknownCellSet
A CellSet of an unknown type.
Definition: UnknownCellSet.h:56
viskores::ListForEach
void ListForEach(Functor &&f, viskores::List< Ts... >, Args &&... args)
For each typename represented by the list, call the functor with a default instance of that type.
Definition: List.h:745
viskores::cont::UncertainCellSet
A CellSet of an uncertain type.
Definition: UncertainCellSet.h:46
viskores::Get
auto Get(const viskores::Tuple< Ts... > &tuple)
Retrieve the object from a viskores::Tuple at the given index.
Definition: Tuple.h:89
viskores::cont::UnknownCellSet::GetCellPointIds
void GetCellPointIds(viskores::Id id, viskores::Id *ptids) const
Definition: UnknownCellSet.h:147
VISKORES_IS_CELL_SET
#define VISKORES_IS_CELL_SET(T)
Definition: CellSet.h:97
VISKORES_LOG_CAST_SUCC
#define VISKORES_LOG_CAST_SUCC(inObj, outObj)
Convenience macro for logging the successful cast of dynamic object.
Definition: Logging.h:232
viskores::cont::UnknownCellSet::AsCellSet
void AsCellSet(CellSetType &cellSet) const
Get the cell set as a known type.
Definition: UnknownCellSet.h:189
viskores::cont::CellSet
Defines the topological structure of the data in a DataSet.
Definition: CellSet.h:36
viskores::cont::UnknownCellSet::InitializeKnownOrUnknownCellSet
void InitializeKnownOrUnknownCellSet(const UnknownCellSet &cellSet, std::true_type)
Definition: UnknownCellSet.h:60
viskores::cont::TypeToString
std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
viskores_cont_export.h
viskores::cont::UnknownCellSet::GetNumberOfFaces
viskores::Id GetNumberOfFaces() const
Definition: UnknownCellSet.h:126
VISKORES_IS_LIST
#define VISKORES_IS_LIST(type)
Checks that the argument is a proper list.
Definition: List.h:77