1 | /** |
2 | * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved. |
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 | * \author Hechong.xyf |
17 | * \date Mar 2018 |
18 | * \brief Interface of AiLego Utility Hyper Cube |
19 | */ |
20 | |
21 | #ifndef __AILEGO_CONTAINER_HYPERCUBE_H__ |
22 | #define __AILEGO_CONTAINER_HYPERCUBE_H__ |
23 | |
24 | #include <map> |
25 | #include <string> |
26 | #include "cube.h" |
27 | |
28 | namespace ailego { |
29 | |
30 | /*! Hypercube |
31 | */ |
32 | class Hypercube { |
33 | public: |
34 | //! Constructor |
35 | Hypercube(void) : cubes_() {} |
36 | |
37 | //! Constructor |
38 | Hypercube(const Hypercube &rhs) : cubes_(rhs.cubes_) {} |
39 | |
40 | //! Constructor |
41 | Hypercube(Hypercube &&rhs) : cubes_() { |
42 | cubes_.swap(rhs.cubes_); |
43 | } |
44 | |
45 | //! Destructor |
46 | ~Hypercube(void) {} |
47 | |
48 | //! Assignment |
49 | Hypercube &operator=(const Hypercube &rhs) { |
50 | cubes_ = rhs.cubes_; |
51 | return *this; |
52 | } |
53 | |
54 | //! Assignment |
55 | Hypercube &operator=(Hypercube &&rhs) { |
56 | cubes_ = std::move(rhs.cubes_); |
57 | return *this; |
58 | } |
59 | |
60 | //! Overloaded operator [] |
61 | Cube &operator[](const std::string &key) { |
62 | return cubes_[key]; |
63 | } |
64 | |
65 | //! Overloaded operator [] |
66 | Cube &operator[](std::string &&key) { |
67 | return cubes_[std::forward<std::string>(key)]; |
68 | } |
69 | |
70 | //! Test if the element is exist |
71 | bool has(const std::string &key) const { |
72 | return (cubes_.find(key) != cubes_.end()); |
73 | } |
74 | |
75 | //! Test if the hyper cube is empty |
76 | bool empty(void) const { |
77 | return cubes_.empty(); |
78 | } |
79 | |
80 | //! Insert a key-value pair into map |
81 | bool insert(const std::string &key, Cube &&val) { |
82 | return cubes_.emplace(key, std::forward<Cube>(val)).second; |
83 | } |
84 | |
85 | //! Insert a key-value pair into map |
86 | bool insert(std::string &&key, Cube &&val) { |
87 | return cubes_ |
88 | .emplace(std::forward<std::string>(key), std::forward<Cube>(val)) |
89 | .second; |
90 | } |
91 | |
92 | //! Insert a key-value pair into map |
93 | template <typename T> |
94 | bool insert(const std::string &key, T &&val) { |
95 | return cubes_.emplace(key, Cube(std::forward<T>(val))).second; |
96 | } |
97 | |
98 | //! Insert a key-value pair into map |
99 | template <typename T> |
100 | bool insert(std::string &&key, T &&val) { |
101 | return cubes_ |
102 | .emplace(std::forward<std::string>(key), Cube(std::forward<T>(val))) |
103 | .second; |
104 | } |
105 | |
106 | //! Insert or assign a key-value pair to map |
107 | void insert_or_assign(const std::string &key, Cube &&val) { |
108 | auto it = cubes_.lower_bound(key); |
109 | if (it != cubes_.end() && it->first == key) { |
110 | it->second = std::forward<Cube>(val); |
111 | } else { |
112 | cubes_.emplace_hint(it, key, std::forward<Cube>(val)); |
113 | } |
114 | } |
115 | |
116 | //! Insert or assign a key-value pair to map |
117 | void insert_or_assign(std::string &&key, Cube &&val) { |
118 | auto it = cubes_.lower_bound(key); |
119 | if (it != cubes_.end() && it->first == key) { |
120 | it->second = std::forward<Cube>(val); |
121 | } else { |
122 | cubes_.emplace_hint(it, std::forward<std::string>(key), |
123 | std::forward<Cube>(val)); |
124 | } |
125 | } |
126 | |
127 | //! Insert or assign a key-value pair to map |
128 | template <typename T> |
129 | void insert_or_assign(const std::string &key, T &&val) { |
130 | auto it = cubes_.lower_bound(key); |
131 | if (it != cubes_.end() && it->first == key) { |
132 | it->second = Cube(std::forward<T>(val)); |
133 | } else { |
134 | cubes_.emplace_hint(it, key, Cube(std::forward<T>(val))); |
135 | } |
136 | } |
137 | |
138 | //! Insert or assign a key-value pair to map |
139 | template <typename T> |
140 | void insert_or_assign(std::string &&key, T &&val) { |
141 | auto it = cubes_.lower_bound(key); |
142 | if (it != cubes_.end() && it->first == key) { |
143 | it->second = Cube(std::forward<T>(val)); |
144 | } else { |
145 | cubes_.emplace_hint(it, std::forward<std::string>(key), |
146 | Cube(std::forward<T>(val))); |
147 | } |
148 | } |
149 | |
150 | //! Clear the map |
151 | void clear(void) { |
152 | cubes_.clear(); |
153 | } |
154 | |
155 | //! Swap the map |
156 | void swap(Hypercube &rhs) { |
157 | cubes_.swap(rhs.cubes_); |
158 | } |
159 | |
160 | //! Erase the pair via a key |
161 | bool erase(const std::string &key) { |
162 | auto iter = cubes_.find(key); |
163 | if (iter != cubes_.end()) { |
164 | cubes_.erase(iter); |
165 | return true; |
166 | } |
167 | return false; |
168 | } |
169 | |
170 | //! Retrieve the value via a key |
171 | bool get(const std::string &key, Cube *out) const { |
172 | auto iter = cubes_.find(key); |
173 | if (iter != cubes_.end()) { |
174 | *out = iter->second; |
175 | return true; |
176 | } |
177 | return false; |
178 | } |
179 | |
180 | //! Retrieve the value via a key |
181 | Cube *get(const std::string &key) { |
182 | auto iter = cubes_.find(key); |
183 | if (iter != cubes_.end()) { |
184 | return &iter->second; |
185 | } |
186 | return nullptr; |
187 | } |
188 | |
189 | //! Retrieve the value via a key |
190 | const Cube *get(const std::string &key) const { |
191 | auto iter = cubes_.find(key); |
192 | if (iter != cubes_.end()) { |
193 | return &iter->second; |
194 | } |
195 | return nullptr; |
196 | } |
197 | |
198 | //! Retrieve the value via a key |
199 | template <typename T> |
200 | bool get(const std::string &key, T *out) const { |
201 | auto iter = cubes_.find(key); |
202 | if (iter != cubes_.end()) { |
203 | if (iter->second.compatible<T>()) { |
204 | *out = iter->second.unsafe_cast<T>(); |
205 | return true; |
206 | } |
207 | } |
208 | return false; |
209 | } |
210 | |
211 | //! Retrieve the value via a key |
212 | template <typename T> |
213 | T &get(const std::string &key, T &def) { |
214 | auto iter = cubes_.find(key); |
215 | if (iter != cubes_.end()) { |
216 | if (iter->second.compatible<T>()) { |
217 | return iter->second.unsafe_cast<T>(); |
218 | } |
219 | } |
220 | return def; |
221 | } |
222 | |
223 | //! Retrieve the value via a key |
224 | template <typename T> |
225 | const T &get(const std::string &key, const T &def) const { |
226 | auto iter = cubes_.find(key); |
227 | if (iter != cubes_.end()) { |
228 | if (iter->second.compatible<T>()) { |
229 | return iter->second.unsafe_cast<T>(); |
230 | } |
231 | } |
232 | return def; |
233 | } |
234 | |
235 | //! Merge another hyper cube |
236 | void merge(const Hypercube &rhs) { |
237 | for (const auto &it : rhs.cubes_) { |
238 | auto iter = cubes_.find(it.first); |
239 | if (iter != cubes_.end()) { |
240 | iter->second = it.second; |
241 | } else { |
242 | cubes_.emplace(it.first, it.second); |
243 | } |
244 | } |
245 | } |
246 | |
247 | //! Merge another hyper cube |
248 | void merge(Hypercube &&rhs) { |
249 | for (auto &it : rhs.cubes_) { |
250 | auto iter = cubes_.find(it.first); |
251 | if (iter != cubes_.end()) { |
252 | iter->second = std::move(it.second); |
253 | } else { |
254 | cubes_.emplace(std::move(it.first), std::move(it.second)); |
255 | } |
256 | } |
257 | } |
258 | |
259 | //! Retrieve the cubes |
260 | const std::map<std::string, Cube> &cubes(void) const { |
261 | return cubes_; |
262 | } |
263 | |
264 | //! Retrieve the cubes |
265 | std::map<std::string, Cube> *mutable_cubes(void) { |
266 | return &cubes_; |
267 | } |
268 | |
269 | private: |
270 | std::map<std::string, Cube> cubes_; |
271 | }; |
272 | |
273 | } // namespace ailego |
274 | |
275 | #endif // __AILEGO_CONTAINER_HYPERCUBE_H__ |
276 | |