type.hpp
1 // Copyright (C) 2018-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 #pragma once
6 
7 #include <cstdint>
8 #include <cstring>
9 #include <functional>
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "ngraph/ngraph_visibility.hpp"
16 
17 namespace ngraph
18 {
19  /// Supports three functions, is_type<Type>, as_type<Type>, and as_type_ptr<Type> for type-safe
20  /// dynamic conversions via static_cast/static_ptr_cast without using C++ RTTI.
21  /// Type must have a static type_info member and a virtual get_type_info() member that
22  /// returns a reference to its type_info member.
23 
24  /// Type information for a type system without inheritance; instances have exactly one type not
25  /// related to any other type.
26  struct NGRAPH_API DiscreteTypeInfo
27  {
28  const char* name;
29  uint64_t version;
30  // A pointer to a parent type info; used for casting and inheritance traversal, not for
31  // exact type identification
32  const DiscreteTypeInfo* parent;
33 
34  DiscreteTypeInfo() = default;
35 
36  constexpr DiscreteTypeInfo(const char* _name,
37  uint64_t _version,
38  const DiscreteTypeInfo* _parent = nullptr)
39  : name(_name)
40  , version(_version)
41  , parent(_parent)
42  {
43  }
44 
45  bool is_castable(const DiscreteTypeInfo& target_type) const
46  {
47  return *this == target_type || (parent && parent->is_castable(target_type));
48  }
49 
50  // For use as a key
51  bool operator<(const DiscreteTypeInfo& b) const
52  {
53  return version < b.version || (version == b.version && strcmp(name, b.name) < 0);
54  }
55  bool operator<=(const DiscreteTypeInfo& b) const
56  {
57  return version < b.version || (version == b.version && strcmp(name, b.name) <= 0);
58  }
59  bool operator>(const DiscreteTypeInfo& b) const
60  {
61  return version < b.version || (version == b.version && strcmp(name, b.name) > 0);
62  }
63  bool operator>=(const DiscreteTypeInfo& b) const
64  {
65  return version < b.version || (version == b.version && strcmp(name, b.name) >= 0);
66  }
67  bool operator==(const DiscreteTypeInfo& b) const
68  {
69  return version == b.version && strcmp(name, b.name) == 0;
70  }
71  bool operator!=(const DiscreteTypeInfo& b) const
72  {
73  return version != b.version || strcmp(name, b.name) != 0;
74  }
75  };
76 
77  /// \brief Tests if value is a pointer/shared_ptr that can be statically cast to a
78  /// Type*/shared_ptr<Type>
79  template <typename Type, typename Value>
80  typename std::enable_if<
81  std::is_convertible<
82  decltype(std::declval<Value>()->get_type_info().is_castable(Type::type_info)),
83  bool>::value,
84  bool>::type
85  is_type(Value value)
86  {
87  return value->get_type_info().is_castable(Type::type_info);
88  }
89 
90  /// Casts a Value* to a Type* if it is of type Type, nullptr otherwise
91  template <typename Type, typename Value>
92  typename std::enable_if<
93  std::is_convertible<decltype(static_cast<Type*>(std::declval<Value>())), Type*>::value,
94  Type*>::type
95  as_type(Value value)
96  {
97  return is_type<Type>(value) ? static_cast<Type*>(value) : nullptr;
98  }
99 
100  /// Casts a std::shared_ptr<Value> to a std::shared_ptr<Type> if it is of type
101  /// Type, nullptr otherwise
102  template <typename Type, typename Value>
103  typename std::enable_if<
104  std::is_convertible<decltype(std::static_pointer_cast<Type>(std::declval<Value>())),
105  std::shared_ptr<Type>>::value,
106  std::shared_ptr<Type>>::type
107  as_type_ptr(Value value)
108  {
109  return is_type<Type>(value) ? std::static_pointer_cast<Type>(value)
110  : std::shared_ptr<Type>();
111  }
112 } // namespace ngraph
113 
114 namespace std
115 {
116  template <>
117  struct NGRAPH_API hash<ngraph::DiscreteTypeInfo>
118  {
119  size_t operator()(const ngraph::DiscreteTypeInfo& k) const;
120  };
121 } // namespace std
The Intel nGraph C++ API.
Definition: attribute_adapter.hpp:16
std::enable_if< std::is_convertible< decltype(std::static_pointer_cast< Type >std::declval< Value >))), std::shared_ptr< Type > >::value, std::shared_ptr< Type > >::type as_type_ptr(Value value)
Definition: type.hpp:107
std::enable_if< std::is_convertible< decltype(static_cast< Type * >std::declval< Value >))), Type * >::value, Type * >::type as_type(Value value)
Casts a Value* to a Type* if it is of type Type, nullptr otherwise.
Definition: type.hpp:95
Definition: type.hpp:27