• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
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 #ifndef RUNTIME_INCLUDE_TAIHE_OPTIONAL_HPP_
16 #define RUNTIME_INCLUDE_TAIHE_OPTIONAL_HPP_
17 // NOLINTBEGIN
18 
19 #include <taihe/optional.abi.h>
20 #include <taihe/common.hpp>
21 
22 #include <cstddef>
23 #include <cstdlib>
24 #include <memory>
25 #include <optional>
26 #include <stdexcept>
27 #include <utility>
28 
29 namespace taihe {
30 template <typename cpp_owner_t>
31 struct optional_view;
32 
33 template <typename cpp_owner_t>
34 struct optional;
35 
36 template <typename cpp_owner_t>
37 struct optional_view {
optional_viewtaihe::optional_view38     optional_view(cpp_owner_t *handle) noexcept : m_handle(handle) {}  // main constructor
39 
optional_viewtaihe::optional_view40     optional_view() noexcept : optional_view(nullptr) {}
41 
optional_viewtaihe::optional_view42     optional_view(std::nullopt_t) : optional_view(nullptr) {}
43 
operator booltaihe::optional_view44     explicit operator bool() const
45     {
46         return m_handle;
47     }
48 
has_valuetaihe::optional_view49     bool has_value() const
50     {
51         return m_handle;
52     }
53 
operator ->taihe::optional_view54     cpp_owner_t const *operator->() const
55     {
56         return m_handle;
57     }
58 
operator *taihe::optional_view59     cpp_owner_t const &operator*() const
60     {
61         return *m_handle;
62     }
63 
valuetaihe::optional_view64     cpp_owner_t const &value() const
65     {
66         return *m_handle;
67     }
68 
value_ortaihe::optional_view69     cpp_owner_t value_or(cpp_owner_t &&default_value) const
70     {
71         if (m_handle) {
72             return *m_handle;
73         } else {
74             return std::move(default_value);
75         }
76     }
77 
operator ==(optional_view const & lhs,optional_view const & rhs)78     friend bool operator==(optional_view const &lhs, optional_view const &rhs)
79     {
80         return (!lhs && !rhs) || (lhs && rhs && *lhs == *rhs);
81     }
82 
operator !=(optional_view const & lhs,optional_view const & rhs)83     friend bool operator!=(optional_view const &lhs, optional_view const &rhs)
84     {
85         return !(lhs == rhs);
86     }
87 
88 protected:
89     cpp_owner_t *m_handle;
90 };
91 
92 template <typename cpp_owner_t>
93 struct optional : public optional_view<cpp_owner_t> {
optionaltaihe::optional94     explicit optional(cpp_owner_t *handle) noexcept : optional_view<cpp_owner_t>(handle) {}  // main constructor
95 
optionaltaihe::optional96     optional() noexcept : optional(nullptr) {}
97 
optionaltaihe::optional98     optional(std::nullopt_t) : optional(nullptr) {}
99 
100     template <typename... Args>
optionaltaihe::optional101     optional(std::in_place_t, Args &&...args) : optional(new cpp_owner_t(std::forward<Args>(args)...))
102     {
103     }
104 
105     // TODO: Deprecate this
106     template <typename... Args>
maketaihe::optional107     static optional make(Args &&...args)
108     {
109         return optional(std::in_place, std::forward<Args>(args)...);
110     }
111 
112     template <typename... Args>
emplacetaihe::optional113     cpp_owner_t &emplace(Args &&...args)
114     {
115         if (this->m_handle) {
116             delete this->m_handle;
117         }
118         this->m_handle = new cpp_owner_t(std::forward<Args>(args)...);
119         return *this->m_handle;
120     }
121 
resettaihe::optional122     void reset()
123     {
124         if (this->m_handle) {
125             delete this->m_handle;
126             this->m_handle = nullptr;
127         }
128     }
129 
optionaltaihe::optional130     optional(optional_view<cpp_owner_t> const &other) : optional(other ? new cpp_owner_t(*other) : nullptr) {}
131 
optionaltaihe::optional132     optional(optional<cpp_owner_t> const &other) : optional(other ? new cpp_owner_t(*other) : nullptr) {}
133 
optionaltaihe::optional134     optional(optional<cpp_owner_t> &&other) : optional(std::exchange(other.m_handle, nullptr)) {}
135 
operator =taihe::optional136     optional &operator=(optional other)
137     {
138         std::swap(this->m_handle, other.m_handle);
139         return *this;
140     }
141 
~optionaltaihe::optional142     ~optional()
143     {
144         if (this->m_handle) {
145             delete this->m_handle;
146         }
147     }
148 };
149 
150 template <typename cpp_owner_t>
151 struct as_abi<optional_view<cpp_owner_t>> {
152     using type = struct TOptional;
153 };
154 
155 template <typename cpp_owner_t>
156 struct as_abi<optional<cpp_owner_t>> {
157     using type = struct TOptional;
158 };
159 
160 template <typename cpp_owner_t>
161 struct as_param<optional<cpp_owner_t>> {
162     using type = optional_view<cpp_owner_t>;
163 };
164 }  // namespace taihe
165 
166 template <typename cpp_owner_t>
167 struct std::hash<taihe::optional<cpp_owner_t>> {
operator ()std::hash168     std::size_t operator()(taihe::optional_view<cpp_owner_t> val) const
169     {
170         return val ? std::hash<cpp_owner_t>()(*val) + 0x9e3779b9 : 0;
171     }
172 };
173 // NOLINTEND
174 #endif  // RUNTIME_INCLUDE_TAIHE_OPTIONAL_HPP_