type.hpp
1 //*****************************************************************************
2 // Copyright 2017-2021 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //*****************************************************************************
16 
17 #pragma once
18 
19 #include <cstdint>
20 #include <cstring>
21 #include <functional>
22 #include <memory>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 #include "ngraph/ngraph_visibility.hpp"
28 
29 namespace ngraph
30 {
31  /// Supports three functions, is_type<Type>, as_type<Type>, and as_type_ptr<Type> for type-safe
32  /// dynamic conversions via static_cast/static_ptr_cast without using C++ RTTI.
33  /// Type must have a static type_info member and a virtual get_type_info() member that
34  /// returns a reference to its type_info member.
35 
36  /// Type information for a type system without inheritance; instances have exactly one type not
37  /// related to any other type.
38  struct NGRAPH_API DiscreteTypeInfo
39  {
40  const char* name;
41  uint64_t version;
42  // A pointer to a parent type info; used for casting and inheritance traversal, not for
43  // exact type identification
44  const DiscreteTypeInfo* parent;
45 
46  DiscreteTypeInfo() = default;
47 
48  constexpr DiscreteTypeInfo(const char* _name,
49  uint64_t _version,
50  const DiscreteTypeInfo* _parent = nullptr)
51  : name(_name)
52  , version(_version)
53  , parent(_parent)
54  {
55  }
56 
57  bool is_castable(const DiscreteTypeInfo& target_type) const
58  {
59  return *this == target_type || (parent && parent->is_castable(target_type));
60  }
61 
62  // For use as a key
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 || (version == b.version && strcmp(name, b.name) <= 0);
70  }
71  bool operator>(const DiscreteTypeInfo& b) const
72  {
73  return version < b.version || (version == b.version && strcmp(name, b.name) > 0);
74  }
75  bool operator>=(const DiscreteTypeInfo& b) const
76  {
77  return version < b.version || (version == b.version && strcmp(name, b.name) >= 0);
78  }
79  bool operator==(const DiscreteTypeInfo& b) const
80  {
81  return version == b.version && strcmp(name, b.name) == 0;
82  }
83  bool operator!=(const DiscreteTypeInfo& b) const
84  {
85  return version != b.version || strcmp(name, b.name) != 0;
86  }
87  };
88 
89  /// \brief Tests if value is a pointer/shared_ptr that can be statically cast to a
90  /// Type*/shared_ptr<Type>
91  template <typename Type, typename Value>
92  typename std::enable_if<
93  std::is_convertible<
94  decltype(std::declval<Value>()->get_type_info().is_castable(Type::type_info)),
95  bool>::value,
96  bool>::type
97  is_type(Value value)
98  {
99  return value->get_type_info().is_castable(Type::type_info);
100  }
101 
102  /// Casts a Value* to a Type* if it is of type Type, nullptr otherwise
103  template <typename Type, typename Value>
104  typename std::enable_if<
105  std::is_convertible<decltype(static_cast<Type*>(std::declval<Value>())), Type*>::value,
106  Type*>::type
107  as_type(Value value)
108  {
109  return is_type<Type>(value) ? static_cast<Type*>(value) : nullptr;
110  }
111 
112  /// Casts a std::shared_ptr<Value> to a std::shared_ptr<Type> if it is of type
113  /// Type, nullptr otherwise
114  template <typename Type, typename Value>
115  typename std::enable_if<
116  std::is_convertible<decltype(std::static_pointer_cast<Type>(std::declval<Value>())),
117  std::shared_ptr<Type>>::value,
118  std::shared_ptr<Type>>::type
119  as_type_ptr(Value value)
120  {
121  return is_type<Type>(value) ? std::static_pointer_cast<Type>(value)
122  : std::shared_ptr<Type>();
123  }
124 }
125 
126 namespace std
127 {
128  template <>
129  struct NGRAPH_API hash<ngraph::DiscreteTypeInfo>
130  {
131  size_t operator()(const ngraph::DiscreteTypeInfo& k) const;
132  };
133 }
The Intel nGraph C++ API.
Definition: attribute_adapter.hpp:28
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:119
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:107
Definition: type.hpp:39