tvm
optional.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
24 #ifndef TVM_RUNTIME_CONTAINER_OPTIONAL_H_
25 #define TVM_RUNTIME_CONTAINER_OPTIONAL_H_
26 
27 #include <utility>
28 
29 #include "./base.h"
30 
31 namespace tvm {
32 namespace runtime {
33 
35 struct NullOptType {};
36 
50 template <typename T>
51 class Optional : public ObjectRef {
52  public:
53  using ContainerType = typename T::ContainerType;
54  static_assert(std::is_base_of<ObjectRef, T>::value, "Optional is only defined for ObjectRef.");
55  // default constructors.
56  Optional() = default;
57  Optional(const Optional<T>&) = default;
58  Optional(Optional<T>&&) = default;
59  Optional<T>& operator=(const Optional<T>&) = default;
66  explicit Optional(ObjectPtr<Object> ptr) : ObjectRef(ptr) {}
68  Optional(NullOptType) {} // NOLINT(*)
69  // nullptr handling.
70  // disallow implicit conversion as 0 can be implicitly converted to nullptr_t
71  explicit Optional(std::nullptr_t) {}
72  Optional<T>& operator=(std::nullptr_t) {
73  data_ = nullptr;
74  return *this;
75  }
76  // normal value handling.
77  Optional(T other) // NOLINT(*)
78  : ObjectRef(std::move(other)) {}
79  Optional<T>& operator=(T other) {
80  ObjectRef::operator=(std::move(other));
81  return *this;
82  }
83  // delete the int constructor
84  // since Optional<Integer>(0) is ambiguious
85  // 0 can be implicitly casted to nullptr_t
86  explicit Optional(int val) = delete;
87  Optional<T>& operator=(int val) = delete;
92  T value() const {
93  ICHECK(data_ != nullptr);
94  return T(data_);
95  }
100  const ContainerType* get() const { return static_cast<ContainerType*>(data_.get()); }
105  T value_or(T default_value) const { return data_ != nullptr ? T(data_) : default_value; }
106 
108  explicit operator bool() const { return *this != nullptr; }
109  // operator overloadings
110  bool operator==(std::nullptr_t) const { return data_ == nullptr; }
111  bool operator!=(std::nullptr_t) const { return data_ != nullptr; }
112  auto operator==(const Optional<T>& other) const {
113  // support case where sub-class returns a symbolic ref type.
114  using RetType = decltype(value() == other.value());
115  if (same_as(other)) return RetType(true);
116  if (*this != nullptr && other != nullptr) {
117  return value() == other.value();
118  } else {
119  // one of them is nullptr.
120  return RetType(false);
121  }
122  }
123  auto operator!=(const Optional<T>& other) const {
124  // support case where sub-class returns a symbolic ref type.
125  using RetType = decltype(value() != other.value());
126  if (same_as(other)) return RetType(false);
127  if (*this != nullptr && other != nullptr) {
128  return value() != other.value();
129  } else {
130  // one of them is nullptr.
131  return RetType(true);
132  }
133  }
134  auto operator==(const T& other) const {
135  using RetType = decltype(value() == other);
136  if (same_as(other)) return RetType(true);
137  if (*this != nullptr) return value() == other;
138  return RetType(false);
139  }
140  auto operator!=(const T& other) const { return !(*this == other); }
141  template <typename U>
142  auto operator==(const U& other) const {
143  using RetType = decltype(value() == other);
144  if (*this == nullptr) return RetType(false);
145  return value() == other;
146  }
147  template <typename U>
148  auto operator!=(const U& other) const {
149  using RetType = decltype(value() != other);
150  if (*this == nullptr) return RetType(true);
151  return value() != other;
152  }
153  static constexpr bool _type_is_nullable = true;
154 };
155 
156 template <typename ObjectRefType, typename>
158  if (auto* ptr = this->as<typename ObjectRefType::ContainerType>()) {
159  return GetRef<ObjectRefType>(ptr);
160  } else {
161  return NullOptType{};
162  }
163 }
164 
165 } // namespace runtime
166 
167 // expose the functions to the root namespace.
168 using runtime::Optional;
170 } // namespace tvm
171 
172 #endif // TVM_RUNTIME_CONTAINER_OPTIONAL_H_
A custom smart pointer for Object.
Definition: object.h:362
Base class of all object reference.
Definition: object.h:519
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:605
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:906
bool same_as(const ObjectRef &other) const
Comparator.
Definition: object.h:530
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
typename T::ContainerType ContainerType
Definition: optional.h:53
const ContainerType * get() const
Definition: optional.h:100
T value_or(T default_value) const
Definition: optional.h:105
auto operator!=(const Optional< T > &other) const
Definition: optional.h:123
Optional(Optional< T > &&)=default
auto operator==(const U &other) const
Definition: optional.h:142
bool operator!=(std::nullptr_t) const
Definition: optional.h:111
Optional< T > & operator=(const Optional< T > &)=default
Optional(NullOptType)
Nullopt handling.
Definition: optional.h:68
Optional(T other)
Definition: optional.h:77
auto operator!=(const T &other) const
Definition: optional.h:140
static constexpr bool _type_is_nullable
Definition: optional.h:153
Optional(std::nullptr_t)
Definition: optional.h:71
Optional< T > & operator=(int val)=delete
Optional(const Optional< T > &)=default
Optional< T > & operator=(T other)
Definition: optional.h:79
Optional(ObjectPtr< Object > ptr)
Construct from an ObjectPtr whose type already matches the ContainerType.
Definition: optional.h:66
Optional< T > & operator=(std::nullptr_t)
Definition: optional.h:72
auto operator==(const Optional< T > &other) const
Definition: optional.h:112
auto operator==(const T &other) const
Definition: optional.h:134
auto operator!=(const U &other) const
Definition: optional.h:148
bool operator==(std::nullptr_t) const
Definition: optional.h:110
Optional(int val)=delete
T value() const
Definition: optional.h:92
Optional< T > & operator=(Optional< T > &&)=default
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
constexpr runtime::NullOptType NullOpt
Definition: optional.h:169
Helper to represent nullptr for optional.
Definition: optional.h:35