TensorFlow Serving C++ API Documentation
any_ptr.h
1 /* Copyright 2016 Google Inc. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7  http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_SERVING_UTIL_ANY_PTR_H_
17 #define TENSORFLOW_SERVING_UTIL_ANY_PTR_H_
18 
19 #include <cstddef>
20 #include <memory>
21 
22 namespace tensorflow {
23 namespace serving {
24 
65 class AnyPtr {
66  public:
68  AnyPtr() : type_id_(FastTypeId<void>()), ptr_(nullptr) {}
69 
71  AnyPtr(std::nullptr_t) : AnyPtr() {} // NOLINT
72 
74  template <typename T>
75  AnyPtr(T* ptr) // NOLINT
76  : type_id_(FastTypeId<T>()),
77  // We need a double cast here, first to drop the type, and second to
78  // drop constness. We always cast back to the appropriate type and
79  // constness in get<>(), since FastTypeId is different for a const and
80  // non-const T.
81  ptr_(const_cast<void*>(reinterpret_cast<const void*>(ptr))) {}
82 
84  template <typename T>
85  T* get() const {
86  if (type_id_ != FastTypeId<T>()) {
87  return nullptr;
88  }
89  return reinterpret_cast<T*>(ptr_);
90  }
91 
92  private:
93  template <typename Type>
94  static size_t FastTypeId() {
95  // Use a static variable to get a unique per-type address.
96  static int dummy;
97  return reinterpret_cast<std::size_t>(&dummy);
98  }
99 
100  // The code for the type of 'ptr_'.
101  std::size_t type_id_;
102 
103  // The underlying pointer.
104  void* ptr_;
105 };
106 
110  public:
112  UniqueAnyPtr() = default;
113  UniqueAnyPtr(std::nullptr_t) : UniqueAnyPtr() {} // NOLINT
114 
116  template <typename T>
117  explicit UniqueAnyPtr(std::unique_ptr<T> ptr)
118  : ptr_(ptr.release()), deleter_(DeleterForType<T>()) {}
119 
120  ~UniqueAnyPtr() { deleter_(ptr_); }
121 
122  // Disable copy.
123  UniqueAnyPtr(const UniqueAnyPtr& other) = delete;
124  UniqueAnyPtr& operator=(const UniqueAnyPtr& other) = delete;
125 
126  // Allow move.
127  UniqueAnyPtr(UniqueAnyPtr&& other) { swap(other); }
128 
129  UniqueAnyPtr& operator=(UniqueAnyPtr&& other) {
130  swap(other);
131  return *this;
132  }
133 
135  template <typename T>
136  T* get() const {
137  return ptr_.get<T>();
138  }
139 
141  const AnyPtr& as_any_ptr() const { return ptr_; }
142 
143  void swap(UniqueAnyPtr& other) {
144  using ::std::swap;
145  swap(ptr_, other.ptr_);
146  swap(deleter_, other.deleter_);
147  }
148 
149  private:
150  // We use a raw function pointer. This eliminates the copy and calling
151  // overhead of std::function.
152  using Deleter = void (*)(AnyPtr ptr);
153 
154  // Returns a 'Deleter' that will delete it's argument as an instance of 'T'.
155  // Always returns the same value for the same 'T'.
156  template <typename T>
157  static Deleter DeleterForType() {
158  return [](AnyPtr ptr) { delete ptr.get<T>(); };
159  }
160 
161  static Deleter NoOpDeleter() {
162  return [](AnyPtr ptr) {};
163  }
164 
165  AnyPtr ptr_ = nullptr;
166  Deleter deleter_ = NoOpDeleter();
167 };
168 
169 } // namespace serving
170 } // namespace tensorflow
171 
172 #endif // TENSORFLOW_SERVING_UTIL_ANY_PTR_H_
AnyPtr()
AnyPtr is void and null by default.
Definition: any_ptr.h:68
T * get() const
Accessor for the underlying pointer if it is of type T, otherwise null.
Definition: any_ptr.h:85
AnyPtr(T *ptr)
Construct from a pointer to any type.
Definition: any_ptr.h:75
AnyPtr(std::nullptr_t)
Implicit construction from nullptr.
Definition: any_ptr.h:71
UniqueAnyPtr()=default
UniqueAnyPtr is void and null by default.
const AnyPtr & as_any_ptr() const
Accessor for the underlying pointer as an AnyPtr.
Definition: any_ptr.h:141
T * get() const
Accessor for the underlying pointer if it is of type T, otherwise null.
Definition: any_ptr.h:136
UniqueAnyPtr(std::unique_ptr< T > ptr)
Construct from a unique pointer to any type.
Definition: any_ptr.h:117