SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
ArcMap.h
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 
11 #ifndef smtk_graph_ArcMap_h
12 #define smtk_graph_ArcMap_h
13 
14 #include "smtk/PublicPointerDefs.h"
15 
16 #include "smtk/graph/ArcImplementation.h"
17 #include "smtk/graph/Directionality.h"
18 
19 #include "smtk/resource/query/BadTypeError.h"
20 
21 #include "smtk/string/Token.h"
22 
23 #include "smtk/common/CompilerInformation.h"
24 #include "smtk/common/RuntimeTypeContainer.h"
25 #include "smtk/common/TypeName.h"
26 
27 #include <set>
28 
29 namespace smtk
30 {
31 namespace resource
32 {
33 class CopyOptions;
34 }
35 namespace graph
36 {
37 
38 class ResourceBase;
39 
48 class SMTKCORE_EXPORT ArcMap
49 {
50 public:
54 
55  ArcMap() {} // NOLINT . MSVC2019 barfs with C2580 on "= default;"
56 
57  template<typename List>
58  ArcMap()
59  {
60  this->insertArcImplementations<List>();
61  }
62 
63  template<typename List>
65  {
66  this->insertArcImplementations<List>();
67  }
68 
70  ArcMap(const ArcMap&) = delete;
71  ArcMap& operator=(const ArcMap&) = delete;
72 
73  virtual ~ArcMap() = default;
74 
81  template<typename ArcTraits>
83  {
84  smtk::string::Token arcTypeName = smtk::common::typeName<ArcTraits>();
85  auto it = m_data.find(arcTypeName);
86  if (it == m_data.end())
87  {
88  return nullptr;
89  }
90  return dynamic_cast<ArcImplementation<ArcTraits>*>(it->second.get());
91  }
92 
93  template<typename ArcTraits>
95  {
96  smtk::string::Token arcTypeName = smtk::common::typeName<ArcTraits>();
97  auto it = m_data.find(arcTypeName);
98  if (it == m_data.end())
99  {
100  return nullptr;
101  }
102  return dynamic_cast<ArcImplementation<ArcTraits>*>(it->second.get());
103  }
104 
105  template<typename ImplementationType>
106  const ImplementationType* at(smtk::string::Token declaredType) const
107  {
108  auto it = m_data.find(declaredType);
109  if (it == m_data.end())
110  {
111  return nullptr;
112  }
113  return dynamic_cast<ImplementationType*>(it->second.get());
114  }
115 
116  template<typename ImplementationType>
117  ImplementationType* at(smtk::string::Token declaredType)
118  {
119  auto it = m_data.find(declaredType);
120  if (it == m_data.end())
121  {
122  return nullptr;
123  }
124  return dynamic_cast<ImplementationType*>(it->second.get());
125  }
127 
135  template<typename Tuple, typename Functor, typename... Args>
136  void invoke(Args&&... args) const
137  {
138  ArcMap::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
139  }
140 
141  template<typename Tuple, typename Functor, typename... Args>
142  void invoke(Args&&... args)
143  {
144  ArcMap::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
145  }
147 
156  // const version
157  template<typename Functor, typename... Args>
158  void invokeRuntime(Args&&... args) const
159  {
160  Functor f;
161  for (const auto& baseArc : this->runtimeBaseTypes())
162  {
163  for (const auto& arcTypeName : this->runtimeTypeNames(baseArc))
164  {
165  f(arcTypeName, *this->at<ArcImplementationBase>(arcTypeName), std::forward<Args>(args)...);
166  }
167  }
168  }
169 
170  // non-const version
171  template<typename Functor, typename... Args>
172  void invokeRuntime(Args&&... args)
173  {
174  Functor f;
175  for (const auto& baseArc : this->runtimeBaseTypes())
176  {
177  for (const auto& arcTypeName : this->runtimeTypeNames(baseArc))
178  {
179  f(arcTypeName, *this->at<ArcImplementationBase>(arcTypeName), std::forward<Args>(args)...);
180  }
181  }
182  }
184 
186  const std::set<smtk::string::Token>& types() const { return m_types; }
187 
207  bool insertRuntimeArcType(
208  smtk::graph::ResourceBase* resource,
209  smtk::string::Token arcType,
210  std::unordered_set<smtk::string::Token> fromNodeSpecs,
211  std::unordered_set<smtk::string::Token> toNodeSpecs,
212  Directionality isDirected);
213 
218  std::unordered_set<smtk::string::Token> runtimeBaseTypes() const;
219 
223  const std::unordered_set<smtk::string::Token>& runtimeTypeNames(
224  smtk::string::Token baseType) const;
225 
227  template<typename ArcImplementationType>
228  const ArcImplementationType& getRuntime(smtk::string::Token arcType) const
229  {
230  auto it = m_data.find(arcType);
231  if (it == m_data.end())
232  {
233  throw smtk::resource::query::BadTypeError(arcType.data());
234  }
235  return *dynamic_cast<ArcImplementationType*>(it->second.get());
236  }
237 
238  template<typename ArcImplementationType>
239  ArcImplementationType& getRuntime(smtk::string::Token arcType)
240  {
241  auto it = m_data.find(arcType);
242  if (it == m_data.end())
243  {
244  throw smtk::resource::query::BadTypeError(arcType.data());
245  }
246  return *dynamic_cast<ArcImplementationType*>(it->second.get());
247  }
248 
261  virtual void copyArcs(
262  const smtk::graph::ResourceBase* source,
263  //const ArcMap& source,
265  smtk::graph::ResourceBase* target);
266 
267 protected:
268  template<typename Type>
269  void insertArcImplementation()
270  {
271  smtk::string::Token arcTypeName = smtk::common::typeName<Type>();
272  auto arcData = std::make_shared<ArcImplementation<Type>>();
273  if (m_data.emplace(arcTypeName, arcData).second)
274  {
275  m_types.insert(arcTypeName);
276  }
277  }
278 
279  // const version
280  template<typename Entry, typename Functor, typename... Args>
281  void invokeFunctor(Args&&... args) const
282  {
283  Functor f;
284  f(this->at<Entry>(), std::forward<Args>(args)...);
285  }
286 
287  // non-const version
288  template<typename Entry, typename Functor, typename... Args>
289  void invokeFunctor(Args&&... args)
290  {
291  Functor f;
292  f(this->at<Entry>(), std::forward<Args>(args)...);
293  }
294 
295  template<typename Tuple>
296  void insertArcImplementations()
297  {
298  ArcMap::insertArcImplementations<0, Tuple>();
299  }
300 
301 private:
302  template<std::size_t I, typename Tuple>
303  inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type
304  insertArcImplementations()
305  {
306  this->insertArcImplementation<typename std::tuple_element<I, Tuple>::type>();
307  ArcMap::insertArcImplementations<I + 1, Tuple>();
308  }
309 
310  template<std::size_t I, typename Tuple>
311  inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type
312  insertArcImplementations()
313  {
314  }
315 
316  // const versions
317  template<std::size_t I, typename Tuple, typename Functor, typename... Args>
318  inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
319  Args&&... args) const
320  {
321  this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
322  std::forward<Args>(args)...);
323  ArcMap::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
324  }
325 
326  // non-const version
327  template<std::size_t I, typename Tuple, typename Functor, typename... Args>
328  inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
329  Args&&... args)
330  {
331  this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
332  std::forward<Args>(args)...);
333  ArcMap::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
334  }
335 
336  // This only needs a const version.
337  template<std::size_t I, typename Tuple, typename Functor, typename... Args>
338  inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type invokeFunctors(
339  Args&&...) const
340  {
341  }
342 
344  std::unordered_map<smtk::string::Token, std::shared_ptr<ArcImplementationBase>> m_data;
347  std::unordered_map<smtk::string::Token, std::unordered_set<smtk::string::Token>> m_runtimeArcs;
349  std::set<smtk::string::Token> m_types;
350 };
351 
352 } // namespace graph
353 } // namespace smtk
354 
355 #endif // smtk_graph_ArcMap_h
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::graph::ArcMap::invokeRuntime
void invokeRuntime(Args &&... args) const
Invoke a Functor (which accepts args) on each run-time arc type in the Tuple.
Definition: ArcMap.h:158
smtk::graph::ArcMap::getRuntime
const ArcImplementationType & getRuntime(smtk::string::Token arcType) const
Return a reference to an arc-type's storage.
Definition: ArcMap.h:228
PublicPointerDefs.h
smtk::graph::ArcMap::types
const std::set< smtk::string::Token > & types() const
Return the type-names of the arc types accepted by this ArcMap instance.
Definition: ArcMap.h:186
smtk::graph::ArcMap::at
const ArcImplementation< ArcTraits > * at() const
Return the arc's implementation object given its trait type.
Definition: ArcMap.h:82
smtk::graph::Directionality
Directionality
An enumeration indicated whether an arc is directed or undirected.
Definition: Directionality.h:25
smtk::graph::ArcMap::invoke
void invoke(Args &&... args) const
Invoke a Functor (which accepts args) on each arc type in the Tuple.
Definition: ArcMap.h:136
smtk::resource::query::BadTypeError
An exception to throw when a type is requested that does not exist in a container.
Definition: BadTypeError.h:34
smtk::common::UUID
Definition: UUID.h:38
TypeName.h
Named type functions.
smtk::resource::CopyOptions
Definition: CopyOptions.h:31
smtk::graph::ArcImplementation
A wrapper around arc type-traits classes that provides API.
Definition: ArcImplementation.h:50
smtk::string::Token::data
const std::string & data() const
Return the string corresponding to the token.
Definition: Token.cxx:46
smtkSuperclassMacro
#define smtkSuperclassMacro(...)
Add a typedef to the superclass of this class.
Definition: SharedFromThis.h:147
smtk::string::Token
A string token identified by an integer.
Definition: Token.h:29
smtk::graph::ArcMap
A container for arcs held by a resource.
Definition: ArcMap.h:48
smtkTypeMacroBase
#define smtkTypeMacroBase(...)
Add typedefs to a class for identifcation.
Definition: SharedFromThis.h:131
smtk::graph::ResourceBase
A non-templated base class for graph resources.
Definition: ResourceBase.h:35
smtk::common::TypeMap
TypeMap is a generalized map for storing and accessing data using a key.
Definition: TypeMap.h:51
smtk::identity
Embeds a type in another class so its type information can be passed as a parameter.
Definition: TupleTraits.h:340