Changeset d6bb78b in mainline for uspace/lib/cpp/include/internal/rbtree_iterators.hpp
- Timestamp:
- 2018-07-05T21:41:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 89bc6460
- Parents:
- 009d78b
- git-author:
- Dzejrou <dzejrou@…> (2018-04-29 19:23:26)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/internal/rbtree_iterators.hpp
r009d78b rd6bb78b 30 30 #define LIBCPP_INTERNAL_RBTREE_ITERATORS 31 31 32 #include <internal/iterator.hpp> 32 33 #include <internal/rbtree_node.hpp> 33 34 #include <iterator> … … 44 45 */ 45 46 47 template<class Value, class Reference, class Pointer, class Size> 48 class rbtree_iterator 49 { 50 public: 51 using value_type = Value; 52 using size_type = Size; 53 using reference = Reference; 54 using pointer = Pointer; 55 using difference_type = ptrdiff_t; 56 57 using iterator_category = bidirectional_iterator_tag; 58 59 rbtree_iterator(rbtree_node<value_type>* current = nullptr, bool end = true) 60 : current_{current}, end_{end} 61 { /* DUMMY BODY */ } 62 63 rbtree_iterator(const rbtree_iterator&) = default; 64 rbtree_iterator& operator=(const rbtree_iterator&) = default; 65 66 reference operator*() const 67 { 68 return current_->value; 69 } 70 71 pointer operator->() const 72 { 73 return ¤t_->value; 74 } 75 76 rbtree_iterator& operator++() 77 { 78 if (current_) 79 { 80 auto bckp = current_; 81 if (current_->right) 82 current_ = current_->right->find_smallest(); 83 else 84 { 85 while (!current_->is_left_child()) 86 { 87 current_ = current_->parent; 88 89 if (!current_ || !current_->parent) 90 { 91 /** 92 * We've gone back to root without 93 * being a left child, which means we 94 * were the last node. 95 */ 96 end_ = true; 97 current_ = bckp; 98 99 return *this; 100 } 101 } 102 103 /** 104 * Now we are a left child, 105 * so the next node we have to visit 106 * is our parent. 107 */ 108 current_ = current_->parent; 109 } 110 } 111 112 return *this; 113 } 114 115 rbtree_iterator operator++(int) 116 { 117 auto tmp = *this; 118 ++(*this); 119 120 return tmp; 121 } 122 123 rbtree_iterator& operator--() 124 { 125 if (end_) 126 { 127 try_undo_end_(); 128 129 return *this; 130 } 131 132 if (current_) 133 { 134 if (current_->left) 135 current_ = current_->left->find_largest(); 136 else if (current_->parent) 137 { 138 while (current_->is_left_child()) 139 current_ = current_->parent; 140 141 /** 142 * We know parent exists here 143 * because we went up from the 144 * left and stopped being left 145 * child (if at any point we happened 146 * to become root then this branch 147 * wouldn't happen). 148 */ 149 current_ = current_->parent; 150 } 151 else // We are root without a left child. 152 end_ = true; 153 } 154 155 return *this; 156 } 157 158 rbtree_iterator operator--(int) 159 { 160 auto tmp = *this; 161 --(*this); 162 163 return tmp; 164 } 165 166 const rbtree_node<value_type>* node() const 167 { 168 return current_; 169 } 170 171 rbtree_node<value_type>* node() 172 { 173 return current_; 174 } 175 176 bool end() const 177 { 178 return end_; 179 } 180 181 private: 182 rbtree_node<value_type>* current_; 183 bool end_; 184 185 void try_undo_end_() 186 { 187 if (!current_) 188 return; 189 190 /** 191 * We can do this if we are past end(). 192 * This means we are the largest. 193 */ 194 if (current_->find_largest() == current_) 195 end_ = false; 196 } 197 }; 198 199 template<class Val, class Ref, class Ptr, class Sz> 200 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz>& lhs, 201 const rbtree_iterator<Val, Ref, Ptr, Sz>& rhs) 202 { 203 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 204 } 205 206 template<class Val, class Ref, class Ptr, class Sz> 207 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz>& lhs, 208 const rbtree_iterator<Val, Ref, Ptr, Sz>& rhs) 209 { 210 return !(lhs == rhs); 211 } 212 46 213 template<class Value, class ConstReference, class ConstPointer, class Size> 47 214 class rbtree_const_iterator 48 215 { 216 using non_const_iterator_type = rbtree_iterator< 217 Value, get_non_const_ref_t<ConstReference>, 218 get_non_const_ptr_t<ConstPointer>, Size 219 >; 220 49 221 public: 50 222 using value_type = Value; … … 62 234 rbtree_const_iterator(const rbtree_const_iterator&) = default; 63 235 rbtree_const_iterator& operator=(const rbtree_const_iterator&) = default; 236 237 rbtree_const_iterator(const non_const_iterator_type& other) 238 : current_{other.node()}, end_{other.end()} 239 { /* DUMMY BODY */ } 240 241 rbtree_const_iterator& operator=(const non_const_iterator_type& other) 242 { 243 current_ = other.node(); 244 end_ = other.end(); 245 246 return *this; 247 } 64 248 65 249 const_reference operator*() const … … 205 389 } 206 390 207 template<class Value, class Reference, class Pointer, class Size> 208 class rbtree_iterator 209 { 210 public: 211 using value_type = Value; 212 using size_type = Size; 213 using reference = Reference; 214 using pointer = Pointer; 215 using difference_type = ptrdiff_t; 216 217 using iterator_category = bidirectional_iterator_tag; 218 219 rbtree_iterator(rbtree_node<value_type>* current = nullptr, bool end = true) 220 : current_{current}, end_{end} 221 { /* DUMMY BODY */ } 222 223 rbtree_iterator(const rbtree_iterator&) = default; 224 rbtree_iterator& operator=(const rbtree_iterator&) = default; 225 226 reference operator*() const 227 { 228 return current_->value; 229 } 230 231 pointer operator->() const 232 { 233 return ¤t_->value; 234 } 235 236 rbtree_iterator& operator++() 237 { 238 if (current_) 239 { 240 auto bckp = current_; 241 if (current_->right) 242 current_ = current_->right->find_smallest(); 243 else 244 { 245 while (!current_->is_left_child()) 246 { 247 current_ = current_->parent; 248 249 if (!current_ || !current_->parent) 250 { 251 /** 252 * We've gone back to root without 253 * being a left child, which means we 254 * were the last node. 255 */ 256 end_ = true; 257 current_ = bckp; 258 259 return *this; 260 } 261 } 262 263 /** 264 * Now we are a left child, 265 * so the next node we have to visit 266 * is our parent. 267 */ 268 current_ = current_->parent; 269 } 270 } 271 272 return *this; 273 } 274 275 rbtree_iterator operator++(int) 276 { 277 auto tmp = *this; 278 ++(*this); 279 280 return tmp; 281 } 282 283 rbtree_iterator& operator--() 284 { 285 if (end_) 286 { 287 try_undo_end_(); 288 289 return *this; 290 } 291 292 if (current_) 293 { 294 if (current_->left) 295 current_ = current_->left->find_largest(); 296 else if (current_->parent) 297 { 298 while (current_->is_left_child()) 299 current_ = current_->parent; 300 301 /** 302 * We know parent exists here 303 * because we went up from the 304 * left and stopped being left 305 * child (if at any point we happened 306 * to become root then this branch 307 * wouldn't happen). 308 */ 309 current_ = current_->parent; 310 } 311 else // We are root without a left child. 312 end_ = true; 313 } 314 315 return *this; 316 } 317 318 rbtree_iterator operator--(int) 319 { 320 auto tmp = *this; 321 --(*this); 322 323 return tmp; 324 } 325 326 const rbtree_node<value_type>* node() const 327 { 328 return current_; 329 } 330 331 rbtree_node<value_type>* node() 332 { 333 return current_; 334 } 335 336 bool end() const 337 { 338 return end_; 339 } 340 341 private: 342 rbtree_node<value_type>* current_; 343 bool end_; 344 345 void try_undo_end_() 346 { 347 if (!current_) 348 return; 349 350 /** 351 * We can do this if we are past end(). 352 * This means we are the largest. 353 */ 354 if (current_->find_largest() == current_) 355 end_ = false; 356 } 357 }; 358 359 template<class Val, class Ref, class Ptr, class Sz> 391 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz> 360 392 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz>& lhs, 393 const rbtree_const_iterator<Val, CRef, CPtr, Sz>& rhs) 394 { 395 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end()); 396 } 397 398 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz> 399 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz>& lhs, 400 const rbtree_const_iterator<Val, CRef, CPtr, Sz>& rhs) 401 { 402 return !(lhs == rhs); 403 } 404 405 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz> 406 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz>& lhs, 361 407 const rbtree_iterator<Val, Ref, Ptr, Sz>& rhs) 362 408 { … … 364 410 } 365 411 366 template<class Val, class Ref, class Ptr, class Sz>367 bool operator!=(const rbtree_ iterator<Val, Ref,Ptr, Sz>& lhs,412 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz> 413 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz>& lhs, 368 414 const rbtree_iterator<Val, Ref, Ptr, Sz>& rhs) 369 415 {
Note:
See TracChangeset
for help on using the changeset viewer.