SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
ArcProperties.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_ArcProperties_h
12 #define smtk_graph_ArcProperties_h
13 
14 #include "smtk/Metaprogramming.h"
15 #include "smtk/common/Visit.h"
16 #include "smtk/graph/OwnershipSemantics.h"
17 #include "smtk/string/Token.h"
18 
19 #include <functional>
20 #include <iterator>
21 #include <set>
22 #include <type_traits>
23 
24 namespace smtk
25 {
26 namespace graph
27 {
28 
30 constexpr inline std::size_t unconstrained()
31 {
32  return std::numeric_limits<std::size_t>::max();
33 }
34 
42 template<typename ArcTraits>
44 {
45  template<class>
46  struct type_sink
47  {
48  using type = void;
49  }; // consume a type and make it `void`
50  template<class T>
51  using type_sink_t = typename type_sink<T>::type;
52 
53 public:
55  template<class T, class = void>
56  struct hasOutVisitor : std::false_type
57  {
58  };
59  template<class T>
60  struct hasOutVisitor<
61  T,
62  type_sink_t<decltype(std::declval<T>().outVisitor(
63  nullptr,
64  std::function<smtk::common::Visited(typename T::ToType const*)>()))>> : std::true_type
65  {
66  };
67 
69  template<class T, class = void>
70  struct hasInVisitor : std::false_type
71  {
72  };
73  template<class T>
74  struct hasInVisitor<
75  T,
76  type_sink_t<decltype(std::declval<T>().inVisitor(
77  nullptr,
78  std::function<smtk::common::Visited(typename T::FromType const*)>()))>> : std::true_type
79  {
80  };
81 
83  template<class T, class = void>
84  struct hasOutNodeVisitor : std::false_type
85  {
86  };
87  template<class T>
89  T,
90  type_sink_t<decltype(std::declval<T>().visitAllOutgoingNodes(
91  nullptr,
92  std::function<smtk::common::Visited(typename T::FromType const*)>()))>> : std::true_type
93  {
94  };
95 
97  template<class T, class = void>
98  struct hasInNodeVisitor : std::false_type
99  {
100  };
101  template<class T>
103  T,
104  type_sink_t<decltype(std::declval<T>().visitAllIncomingNodes(
105  nullptr,
106  std::function<smtk::common::Visited(typename T::ToType const*)>()))>> : std::true_type
107  {
108  };
109 
111  template<class T, class = void>
112  struct hasContains : std::false_type
113  {
114  };
115  template<class T>
116  struct hasContains<
117  T,
118  type_sink_t<decltype(std::declval<T>().contains(
119  static_cast<const typename ArcTraits::FromType*>(nullptr),
120  static_cast<const typename ArcTraits::ToType*>(nullptr)))>> : std::true_type
121  {
122  };
123 
125  template<class T, class = void>
126  struct hasOutDegree : std::false_type
127  {
128  };
129  template<class T>
130  struct hasOutDegree<
131  T,
132  type_sink_t<decltype(std::declval<T>().outDegree(
133  static_cast<const typename ArcTraits::FromType*>(nullptr)))>> : std::true_type
134  {
135  };
136 
138  template<class T, class = void>
139  struct hasInDegree : std::false_type
140  {
141  };
142  template<class T>
143  struct hasInDegree<
144  T,
145  type_sink_t<decltype(std::declval<T>().inDegree(
146  static_cast<const typename ArcTraits::ToType*>(nullptr)))>> : std::true_type
147  {
148  };
149 
151  template<class T, class = void>
152  struct hasConnect : std::false_type
153  {
154  };
155  template<class T>
156  struct hasConnect<
157  T,
158  type_sink_t<decltype(std::declval<T>().connect(
159  static_cast<typename ArcTraits::FromType*>(nullptr),
160  static_cast<typename ArcTraits::ToType*>(nullptr),
161  static_cast<typename ArcTraits::FromType*>(nullptr),
162  static_cast<typename ArcTraits::ToType*>(nullptr)))>> : std::true_type
163  {
164  };
165 
167  template<class T, class = void>
168  struct hasDisconnect : std::false_type
169  {
170  };
171  template<class T>
173  T,
174  type_sink_t<decltype(std::declval<T>().disconnect(
175  static_cast<typename ArcTraits::FromType*>(nullptr),
176  static_cast<typename ArcTraits::ToType*>(nullptr)))>> : std::true_type
177  {
178  };
179 
183  template<class T, class = void>
184  struct hasOnlyForwardIndex : std::false_type
185  {
186  };
187  template<class T>
188  struct hasOnlyForwardIndex<T, type_sink_t<typename T::ForwardIndexOnly>>
189  : std::conditional<T::ForwardIndexOnly::value, std::true_type, std::false_type>::type
190  {
191  };
192 
195  template<class T, class = void>
196  struct hasImmutableMark : std::false_type
197  {
198  };
199  template<class T>
200  struct hasImmutableMark<T, type_sink_t<typename T::Immutable>> : std::true_type
201  {
202  // Complain if we have ForwardIndexOnly but it is not true.
203  static_assert(T::Immutable::value, "Immutable must be true_type if present.");
204  };
205 
207  class isOrdered
208  {
209  public:
210  using type = typename hasOnlyForwardIndex<ArcTraits>::type;
211  static constexpr bool value = type::value;
212  };
213 
220  {
221  public:
222  using type = typename disjunction<
223  // We have an inVisitor but want to disable it (using OnlyForwardIndex)
225  // We do not have an inVisitor but do have an outVisitor
227  static constexpr bool value = type::value;
228  };
229 
232  {
233  public:
234  using type = typename conjunction<
235  // We must have an outVisitor() method.
237  // We must have an inVisitor() method or be marked as only allowing forward traversal.
239  static constexpr bool value = type::value;
240  };
241 
244  {
245  public:
246  using type = typename negation<isImplicit>::type;
247  static constexpr bool value = type::value;
248  };
249 
254  class isMutable
255  {
256  public:
257  using type = typename conjunction<
259  disjunction<
261  isExplicit>>::type;
262  static constexpr bool value = type::value;
263  };
264 
275  {
276  public:
277  using type = typename conjunction<
278  std::is_same<typename ArcTraits::FromType, typename ArcTraits::ToType>,
280  static constexpr bool value = type::value;
281  };
282 
283 protected:
284  template<class T, class = void>
285  struct hasSemantics : std::false_type
286  {
287  inline constexpr OwnershipSemantics operator()() const { return OwnershipSemantics::None; }
288  };
289  template<class T>
290  struct hasSemantics<T, type_sink_t<decltype(T::semantics)>> : std::true_type
291  {
292  inline constexpr OwnershipSemantics operator()() const { return T::semantics; }
293  };
294 
295 public:
312  inline static constexpr OwnershipSemantics ownershipSemantics()
313  {
314  return hasSemantics<ArcTraits>()();
315  }
316 };
317 
319 
320 template<typename T>
321 constexpr
322  typename std::enable_if<std::is_integral<decltype(T::MaxOutDegree)>::value, std::size_t>::type
323  maxOutDegree(std::size_t)
324 {
325  return T::MaxOutDegree;
326 }
327 
328 template<typename T>
329 constexpr std::size_t maxOutDegree(...)
330 {
332 }
334 
336 
337 template<typename T>
338 constexpr
339  typename std::enable_if<std::is_integral<decltype(T::MaxInDegree)>::value, std::size_t>::type
340  maxInDegree(std::size_t)
341 {
342  return T::MaxInDegree;
343 }
344 
345 template<typename T>
346 constexpr std::size_t maxInDegree(...)
347 {
349 }
351 
353 
354 template<typename T>
355 constexpr
356  typename std::enable_if<std::is_integral<decltype(T::MinOutDegree)>::value, std::size_t>::type
357  minOutDegree(std::size_t)
358 {
359  return T::MinOutDegree;
360 }
361 
362 template<typename T>
363 constexpr std::size_t minOutDegree(...)
364 {
365  return 0;
366 }
368 
370 
371 template<typename T>
372 constexpr
373  typename std::enable_if<std::is_integral<decltype(T::MinInDegree)>::value, std::size_t>::type
374  minInDegree(std::size_t)
375 {
376  return T::MinInDegree;
377 }
378 
379 template<typename T>
380 constexpr std::size_t minInDegree(...)
381 {
382  return 0;
383 }
385 
386 } // namespace graph
387 } // namespace smtk
388 
389 #endif
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::graph::OwnershipSemantics
OwnershipSemantics
Indicate whether one arc endpoint "owns" the other.
Definition: OwnershipSemantics.h:19
smtk::graph::ArcProperties::isOrdered
True when the order in which arcs are stored is significant.
Definition: ArcProperties.h:207
smtk::graph::ArcProperties::hasDisconnect
Check that a method exists to remove arcs.
Definition: ArcProperties.h:168
smtk::graph::ArcProperties::hasImmutableMark
Check whether the traits object has been marked immutable.
Definition: ArcProperties.h:196
smtk::graph::ArcProperties::hasOutNodeVisitor
Check that a method exists to visit all nodes with outgoing arcs.
Definition: ArcProperties.h:84
smtk::graph::ArcProperties::isOnlyForwardIndexed
Check whether the arc traits object allows traversal only in the foward direction.
Definition: ArcProperties.h:219
smtk::graph::ArcProperties::hasOnlyForwardIndex
Check whether the arc has bidirectional indexing (the default) or has been marked as having only a fo...
Definition: ArcProperties.h:184
smtk::graph::ArcProperties::hasOutVisitor
Check that a method exists to visit out-nodes given a "from" node.
Definition: ArcProperties.h:56
smtk::graph::ArcProperties::hasInVisitor
Check that a method exists to visit in-nodes given a "to" node.
Definition: ArcProperties.h:70
smtk::negation
A "polyfill" for std::negation, introduced in c++17.
Definition: Metaprogramming.h:62
smtk::graph::ArcProperties::isAutoUndirected
Check whether the traits object is undirected and has identical to/from types.
Definition: ArcProperties.h:274
smtk::graph::maxOutDegree
constexpr std::enable_if< std::is_integral< decltype(T::MaxOutDegree)>::value, std::size_t >::type maxOutDegree(std::size_t)
Return the maximum out-degree of an arc type (or unconstrained() if unspecified).
Definition: ArcProperties.h:323
smtk::disjunction
True when any template parameter is "truthy".
Definition: Metaprogramming.h:47
smtk::graph::ArcProperties::isMutable
Check whether the arc traits object (1) is implicit and has methods to insert and remove arcs; or (2)...
Definition: ArcProperties.h:254
smtk::graph::ArcProperties
Checks that can be performed on arc trait-types.
Definition: ArcProperties.h:43
smtk::graph::minOutDegree
constexpr std::enable_if< std::is_integral< decltype(T::MinOutDegree)>::value, std::size_t >::type minOutDegree(std::size_t)
Return the minimum out-degree of an arc type (or 0 if unspecified).
Definition: ArcProperties.h:357
smtk::graph::ArcProperties::hasContains
Check that a method exists to test existence of an arc.
Definition: ArcProperties.h:112
smtk::conjunction
True when all template parameters are "truthy".
Definition: Metaprogramming.h:28
smtk::graph::ArcProperties::hasInNodeVisitor
Check that a method exists to visit all nodes with incoming arcs.
Definition: ArcProperties.h:98
smtk::graph::maxInDegree
constexpr std::enable_if< std::is_integral< decltype(T::MaxInDegree)>::value, std::size_t >::type maxInDegree(std::size_t)
Return the maximum in-degree of an arc type (or unconstrained() if unspecified).
Definition: ArcProperties.h:340
smtk::graph::unconstrained
constexpr std::size_t unconstrained()
Return a constant used to indicate the maximimum degree of an arc endpoint is unconstrained.
Definition: ArcProperties.h:30
smtk::graph::ArcProperties::isImplicit
True when an arc class provides implementations of required methods; false otherwise.
Definition: ArcProperties.h:231
smtk::graph::ArcProperties::hasSemantics
Definition: ArcProperties.h:285
smtk::graph::ArcProperties::isExplicit
False when an arc class provides implementations of required methods; true otherwise.
Definition: ArcProperties.h:243
smtk::graph::minInDegree
constexpr std::enable_if< std::is_integral< decltype(T::MinInDegree)>::value, std::size_t >::type minInDegree(std::size_t)
Return the minimum in-degree of an arc type (or 0 if unspecified).
Definition: ArcProperties.h:374
smtk::graph::ArcProperties::hasOutDegree
Check that a method exists to compute the out-degree of an arc.
Definition: ArcProperties.h:126
Visit.h
smtk::graph::ArcProperties::hasConnect
Check that a method exists to insert arcs.
Definition: ArcProperties.h:152
smtk::graph::ArcProperties::hasInDegree
Check that a method exists to compute the in-degree of an arc.
Definition: ArcProperties.h:139
smtk::graph::OwnershipSemantics::None
@ None
Neither endpoint owns its neighbor.
smtk::graph::ArcProperties::ownershipSemantics
static constexpr OwnershipSemantics ownershipSemantics()
Check whether the traits object provides ownership semantics and return them.
Definition: ArcProperties.h:312