1 /* 2 * Copyright (c) 2019, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for a generic singly linked list. 32 */ 33 34 #ifndef LINKED_LIST_HPP_ 35 #define LINKED_LIST_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <stdio.h> 40 41 #include "common/const_cast.hpp" 42 #include "common/error.hpp" 43 #include "common/iterator_utils.hpp" 44 45 namespace ot { 46 47 /** 48 * @addtogroup core-linked-list 49 * 50 * @brief 51 * This module includes definitions for OpenThread Singly Linked List. 52 * 53 * @{ 54 * 55 */ 56 57 /** 58 * Represents a linked list entry. 59 * 60 * Provides methods to `GetNext()` and `SetNext()` in the linked list entry. 61 * 62 * Users of this class should follow CRTP-style inheritance, i.e., the `Type` class itself should publicly inherit 63 * from `LinkedListEntry<Type>`. 64 * 65 * The template type `Type` should contain a `mNext` member variable. The `mNext` should be of a type that can be 66 * down-casted to `Type` itself. 67 * 68 */ 69 template <class Type> class LinkedListEntry 70 { 71 public: 72 /** 73 * Gets the next entry in the linked list. 74 * 75 * @returns A pointer to the next entry in the linked list or `nullptr` if at the end of the list. 76 * 77 */ GetNext(void) const78 const Type *GetNext(void) const { return static_cast<const Type *>(static_cast<const Type *>(this)->mNext); } 79 80 /** 81 * Gets the next entry in the linked list. 82 * 83 * @returns A pointer to the next entry in the linked list or `nullptr` if at the end of the list. 84 * 85 */ GetNext(void)86 Type *GetNext(void) { return static_cast<Type *>(static_cast<Type *>(this)->mNext); } 87 88 /** 89 * Sets the next pointer on the entry. 90 * 91 * @param[in] aNext A pointer to the next entry. 92 * 93 */ SetNext(Type * aNext)94 void SetNext(Type *aNext) { static_cast<Type *>(this)->mNext = aNext; } 95 }; 96 97 /** 98 * Represents a singly linked list. 99 * 100 * The template type `Type` should provide `GetNext()` and `SetNext()` methods (which can be realized by `Type` 101 * inheriting from `LinkedListEntry<Type>` class). 102 * 103 */ 104 template <typename Type> class LinkedList 105 { 106 class Iterator; 107 class ConstIterator; 108 109 public: 110 /** 111 * Initializes the linked list. 112 * 113 */ LinkedList(void)114 LinkedList(void) 115 : mHead(nullptr) 116 { 117 } 118 119 /** 120 * Returns the entry at the head of the linked list 121 * 122 * @returns Pointer to the entry at the head of the linked list, or `nullptr` if the list is empty. 123 * 124 */ GetHead(void)125 Type *GetHead(void) { return mHead; } 126 127 /** 128 * Returns the entry at the head of the linked list. 129 * 130 * @returns Pointer to the entry at the head of the linked list, or `nullptr` if the list is empty. 131 * 132 */ GetHead(void) const133 const Type *GetHead(void) const { return mHead; } 134 135 /** 136 * Sets the head of the linked list to a given entry. 137 * 138 * @param[in] aHead A pointer to an entry to set as the head of the linked list. 139 * 140 */ SetHead(Type * aHead)141 void SetHead(Type *aHead) { mHead = aHead; } 142 143 /** 144 * Clears the linked list. 145 * 146 */ Clear(void)147 void Clear(void) { mHead = nullptr; } 148 149 /** 150 * Indicates whether the linked list is empty or not. 151 * 152 * @retval TRUE If the linked list is empty. 153 * @retval FALSE If the linked list is not empty. 154 * 155 */ IsEmpty(void) const156 bool IsEmpty(void) const { return (mHead == nullptr); } 157 158 /** 159 * Pushes an entry at the head of the linked list. 160 * 161 * @param[in] aEntry A reference to an entry to push at the head of linked list. 162 * 163 */ Push(Type & aEntry)164 void Push(Type &aEntry) 165 { 166 aEntry.SetNext(mHead); 167 mHead = &aEntry; 168 } 169 170 /** 171 * Pushes an entry after a given previous existing entry in the linked list. 172 * 173 * @param[in] aEntry A reference to an entry to push into the list. 174 * @param[in] aPrevEntry A reference to a previous entry (new entry @p aEntry will be pushed after this). 175 * 176 */ PushAfter(Type & aEntry,Type & aPrevEntry)177 void PushAfter(Type &aEntry, Type &aPrevEntry) 178 { 179 aEntry.SetNext(aPrevEntry.GetNext()); 180 aPrevEntry.SetNext(&aEntry); 181 } 182 183 /** 184 * Pushes an entry after the tail in the linked list. 185 * 186 * @param[in] aEntry A reference to an entry to push into the list. 187 * 188 */ PushAfterTail(Type & aEntry)189 void PushAfterTail(Type &aEntry) 190 { 191 Type *tail = GetTail(); 192 193 if (tail == nullptr) 194 { 195 Push(aEntry); 196 } 197 else 198 { 199 PushAfter(aEntry, *tail); 200 } 201 } 202 203 /** 204 * Pops an entry from head of the linked list. 205 * 206 * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before. 207 * 208 * @returns The entry that was popped if the list is not empty, or `nullptr` if the list is empty. 209 * 210 */ Pop(void)211 Type *Pop(void) 212 { 213 Type *entry = mHead; 214 215 if (mHead != nullptr) 216 { 217 mHead = mHead->GetNext(); 218 } 219 220 return entry; 221 } 222 223 /** 224 * Pops an entry after a given previous entry. 225 * 226 * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before. 227 * 228 * @param[in] aPrevEntry A pointer to a previous entry. If it is not `nullptr` the entry after this will be popped, 229 * otherwise (if it is `nullptr`) the entry at the head of the list is popped. 230 * 231 * @returns Pointer to the entry that was popped, or `nullptr` if there is no entry to pop. 232 * 233 */ PopAfter(Type * aPrevEntry)234 Type *PopAfter(Type *aPrevEntry) 235 { 236 Type *entry; 237 238 if (aPrevEntry == nullptr) 239 { 240 entry = Pop(); 241 } 242 else 243 { 244 entry = aPrevEntry->GetNext(); 245 246 if (entry != nullptr) 247 { 248 aPrevEntry->SetNext(entry->GetNext()); 249 } 250 } 251 252 return entry; 253 } 254 255 /** 256 * Indicates whether the linked list contains a given entry. 257 * 258 * @param[in] aEntry A reference to an entry. 259 * 260 * @retval TRUE The linked list contains @p aEntry. 261 * @retval FALSE The linked list does not contain @p aEntry. 262 * 263 */ Contains(const Type & aEntry) const264 bool Contains(const Type &aEntry) const 265 { 266 const Type *prev; 267 268 return Find(aEntry, prev) == kErrorNone; 269 } 270 271 /** 272 * Indicates whether the linked list contains an entry matching a given entry indicator. 273 * 274 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 275 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 276 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 277 * 278 * bool Type::Matches(const Indicator &aIndicator) const 279 * 280 * @param[in] aIndicator An entry indicator to match against entries in the list. 281 * 282 * @retval TRUE The linked list contains an entry matching @p aIndicator. 283 * @retval FALSE The linked list contains no entry matching @p aIndicator. 284 * 285 */ ContainsMatching(const Indicator & aIndicator) const286 template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const 287 { 288 return FindMatching(aIndicator) != nullptr; 289 } 290 291 /** 292 * Adds an entry (at the head of the linked list) if it is not already in the list. 293 * 294 * @param[in] aEntry A reference to an entry to add. 295 * 296 * @retval kErrorNone The entry was successfully added at the head of the list. 297 * @retval kErrorAlready The entry is already in the list. 298 * 299 */ Add(Type & aEntry)300 Error Add(Type &aEntry) 301 { 302 Error error = kErrorNone; 303 304 if (Contains(aEntry)) 305 { 306 error = kErrorAlready; 307 } 308 else 309 { 310 Push(aEntry); 311 } 312 313 return error; 314 } 315 316 /** 317 * Removes an entry from the linked list. 318 * 319 * @note This method does not change the removed entry @p aEntry itself (it is `const`), i.e., the entry next 320 * pointer of @p aEntry stays as before. 321 * 322 * @param[in] aEntry A reference to an entry to remove. 323 * 324 * @retval kErrorNone The entry was successfully removed from the list. 325 * @retval kErrorNotFound Could not find the entry in the list. 326 * 327 */ Remove(const Type & aEntry)328 Error Remove(const Type &aEntry) 329 { 330 Type *prev; 331 Error error = Find(aEntry, prev); 332 333 if (error == kErrorNone) 334 { 335 PopAfter(prev); 336 } 337 338 return error; 339 } 340 341 /** 342 * Removes an entry matching a given entry indicator from the linked list. 343 * 344 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 345 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 346 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 347 * 348 * bool Type::Matches(const Indicator &aIndicator) const 349 * 350 * @note This method does not change the removed entry itself (which is returned in case of success), i.e., the 351 * entry next pointer stays as before. 352 * 353 * 354 * @param[in] aIndicator An entry indicator to match against entries in the list. 355 * 356 * @returns A pointer to the removed matching entry if one could be found, or `nullptr` if no matching entry is 357 * found. 358 * 359 */ RemoveMatching(const Indicator & aIndicator)360 template <typename Indicator> Type *RemoveMatching(const Indicator &aIndicator) 361 { 362 Type *prev; 363 Type *entry = FindMatching(aIndicator, prev); 364 365 if (entry != nullptr) 366 { 367 PopAfter(prev); 368 } 369 370 return entry; 371 } 372 373 /** 374 * Removes all entries in the list matching a given entry indicator from the list and adds 375 * them to a new list. 376 * 377 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 378 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 379 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 380 * 381 * bool Type::Matches(const Indicator &aIndicator) const 382 * 383 * @param[in] aIndicator An entry indicator to match against entries in the list. 384 * @param[in] aRemovedList The list to add the removed entries to. 385 * 386 */ RemoveAllMatching(const Indicator & aIndicator,LinkedList & aRemovedList)387 template <typename Indicator> void RemoveAllMatching(const Indicator &aIndicator, LinkedList &aRemovedList) 388 { 389 Type *entry; 390 Type *prev; 391 Type *next; 392 393 for (prev = nullptr, entry = GetHead(); entry != nullptr; entry = next) 394 { 395 next = entry->GetNext(); 396 397 if (entry->Matches(aIndicator)) 398 { 399 PopAfter(prev); 400 aRemovedList.Push(*entry); 401 402 // When the entry is removed from the list 403 // we keep the `prev` pointer same as before. 404 } 405 else 406 { 407 prev = entry; 408 } 409 } 410 } 411 412 /** 413 * Searches within the linked list to find an entry and if found returns a pointer to previous entry. 414 * 415 * @param[in] aEntry A reference to an entry to find. 416 * @param[out] aPrevEntry A pointer to output the previous entry on success (when @p aEntry is found in the list). 417 * @p aPrevEntry is set to `nullptr` if @p aEntry is the head of the list. Otherwise it is 418 * updated to point to the previous entry before @p aEntry in the list. 419 * 420 * @retval kErrorNone The entry was found in the list and @p aPrevEntry was updated successfully. 421 * @retval kErrorNotFound The entry was not found in the list. 422 * 423 */ Find(const Type & aEntry,const Type * & aPrevEntry) const424 Error Find(const Type &aEntry, const Type *&aPrevEntry) const 425 { 426 Error error = kErrorNotFound; 427 428 aPrevEntry = nullptr; 429 430 for (const Type *entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext()) 431 { 432 if (entry == &aEntry) 433 { 434 error = kErrorNone; 435 break; 436 } 437 } 438 439 return error; 440 } 441 442 /** 443 * Searches within the linked list to find an entry and if found returns a pointer to previous entry. 444 * 445 * @param[in] aEntry A reference to an entry to find. 446 * @param[out] aPrevEntry A pointer to output the previous entry on success (when @p aEntry is found in the list). 447 * @p aPrevEntry is set to `nullptr` if @p aEntry is the head of the list. Otherwise it is 448 * updated to point to the previous entry before @p aEntry in the list. 449 * 450 * @retval kErrorNone The entry was found in the list and @p aPrevEntry was updated successfully. 451 * @retval kErrorNotFound The entry was not found in the list. 452 * 453 */ Find(const Type & aEntry,Type * & aPrevEntry)454 Error Find(const Type &aEntry, Type *&aPrevEntry) 455 { 456 return AsConst(this)->Find(aEntry, const_cast<const Type *&>(aPrevEntry)); 457 } 458 459 /** 460 * Searches within a given range of the linked list to find an entry matching a given 461 * indicator. 462 * 463 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 464 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 465 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 466 * 467 * bool Type::Matches(const Indicator &aIndicator) const 468 * 469 * @param[in] aBegin A pointer to the begin of the range. 470 * @param[in] aEnd A pointer to the end of the range, or `nullptr` to search all entries after @p aBegin. 471 * @param[in] aIndicator An indicator to match with entries in the list. 472 * @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list). 473 * @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list. 474 * Otherwise it is updated to point to the previous entry before the matching entry in the 475 * list. 476 * 477 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 478 * 479 */ 480 template <typename Indicator> FindMatching(const Type * aBegin,const Type * aEnd,const Indicator & aIndicator,const Type * & aPrevEntry) const481 const Type *FindMatching(const Type *aBegin, 482 const Type *aEnd, 483 const Indicator &aIndicator, 484 const Type *&aPrevEntry) const 485 { 486 const Type *entry; 487 488 aPrevEntry = nullptr; 489 490 for (entry = aBegin; entry != aEnd; aPrevEntry = entry, entry = entry->GetNext()) 491 { 492 if (entry->Matches(aIndicator)) 493 { 494 break; 495 } 496 } 497 498 return entry; 499 } 500 501 /** 502 * Searches within a given range of the linked list to find an entry matching a given 503 * indicator. 504 * 505 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 506 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 507 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 508 * 509 * bool Type::Matches(const Indicator &aIndicator) const 510 * 511 * @param[in] aBegin A pointer to the begin of the range. 512 * @param[in] aEnd A pointer to the end of the range, or `nullptr` to search all entries after @p aBegin. 513 * @param[in] aIndicator An indicator to match with entries in the list. 514 * @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list). 515 * @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list. 516 * Otherwise it is updated to point to the previous entry before the matching entry in the 517 * list. 518 * 519 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 520 * 521 */ 522 template <typename Indicator> FindMatching(const Type * aBegin,const Type * aEnd,const Indicator & aIndicator,Type * & aPrevEntry)523 Type *FindMatching(const Type *aBegin, const Type *aEnd, const Indicator &aIndicator, Type *&aPrevEntry) 524 { 525 return AsNonConst(FindMatching(aBegin, aEnd, aIndicator, const_cast<const Type *&>(aPrevEntry))); 526 } 527 528 /** 529 * Searches within the linked list to find an entry matching a given indicator. 530 * 531 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 532 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 533 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 534 * 535 * bool Type::Matches(const Indicator &aIndicator) const 536 * 537 * @param[in] aIndicator An indicator to match with entries in the list. 538 * @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list). 539 * @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list. 540 * Otherwise it is updated to point to the previous entry before the matching entry in the 541 * list. 542 * 543 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 544 * 545 */ FindMatching(const Indicator & aIndicator,const Type * & aPrevEntry) const546 template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator, const Type *&aPrevEntry) const 547 { 548 return FindMatching(mHead, nullptr, aIndicator, aPrevEntry); 549 } 550 551 /** 552 * Searches within the linked list to find an entry matching a given indicator, and if found 553 * returns a pointer to its previous entry in the list. 554 * 555 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 556 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 557 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 558 * 559 * bool Type::Matches(const Indicator &aIndicator) const 560 * 561 * @param[in] aIndicator An indicator to match with entries in the list. 562 * @param[out] aPrevEntry A pointer to output the previous entry on success (when a match is found in the list). 563 * @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list. 564 * Otherwise it is updated to point to the previous entry before the matching entry in the 565 * list. 566 * 567 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 568 * 569 */ FindMatching(const Indicator & aIndicator,Type * & aPrevEntry)570 template <typename Indicator> Type *FindMatching(const Indicator &aIndicator, Type *&aPrevEntry) 571 { 572 return AsNonConst(AsConst(this)->FindMatching(aIndicator, const_cast<const Type *&>(aPrevEntry))); 573 } 574 575 /** 576 * Searches within the linked list to find an entry matching a given indicator. 577 * 578 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 579 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 580 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 581 * 582 * bool Type::Matches(const Indicator &aIndicator) const 583 * 584 * @param[in] aIndicator An indicator to match with entries in the list. 585 * 586 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 587 * 588 */ FindMatching(const Indicator & aIndicator) const589 template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator) const 590 { 591 const Type *prev; 592 593 return FindMatching(aIndicator, prev); 594 } 595 596 /** 597 * Searches within the linked list to find an entry matching a given indicator. 598 * 599 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 600 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 601 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 602 * 603 * bool Type::Matches(const Indicator &aIndicator) const 604 * 605 * @param[in] aIndicator An indicator to match with entries in the list. 606 * 607 * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found. 608 * 609 */ FindMatching(const Indicator & aIndicator)610 template <typename Indicator> Type *FindMatching(const Indicator &aIndicator) 611 { 612 return AsNonConst(AsConst(this)->FindMatching(aIndicator)); 613 } 614 615 /** 616 * Returns the tail of the linked list (i.e., the last entry in the list). 617 * 618 * @returns A pointer to the tail entry in the linked list or `nullptr` if the list is empty. 619 * 620 */ GetTail(void) const621 const Type *GetTail(void) const 622 { 623 const Type *tail = mHead; 624 625 if (tail != nullptr) 626 { 627 while (tail->GetNext() != nullptr) 628 { 629 tail = tail->GetNext(); 630 } 631 } 632 633 return tail; 634 } 635 636 /** 637 * Returns the tail of the linked list (i.e., the last entry in the list). 638 * 639 * @returns A pointer to the tail entry in the linked list or `nullptr` if the list is empty. 640 * 641 */ GetTail(void)642 Type *GetTail(void) { return AsNonConst(AsConst(this)->GetTail()); } 643 644 // The following methods are intended to support range-based `for` 645 // loop iteration over the linked-list entries and should not be 646 // used directly. 647 begin(void)648 Iterator begin(void) { return Iterator(GetHead()); } end(void)649 Iterator end(void) { return Iterator(nullptr); } 650 begin(void) const651 ConstIterator begin(void) const { return ConstIterator(GetHead()); } end(void) const652 ConstIterator end(void) const { return ConstIterator(nullptr); } 653 654 private: 655 class Iterator : public ItemPtrIterator<Type, Iterator> 656 { 657 friend class LinkedList; 658 friend class ItemPtrIterator<Type, Iterator>; 659 660 using ItemPtrIterator<Type, Iterator>::mItem; 661 Iterator(Type * aItem)662 explicit Iterator(Type *aItem) 663 : ItemPtrIterator<Type, Iterator>(aItem) 664 { 665 } 666 Advance(void)667 void Advance(void) { mItem = mItem->GetNext(); } 668 }; 669 670 class ConstIterator : public ItemPtrIterator<const Type, ConstIterator> 671 { 672 friend class LinkedList; 673 friend class ItemPtrIterator<const Type, ConstIterator>; 674 675 using ItemPtrIterator<const Type, ConstIterator>::mItem; 676 ConstIterator(const Type * aItem)677 explicit ConstIterator(const Type *aItem) 678 : ItemPtrIterator<const Type, ConstIterator>(aItem) 679 { 680 } 681 Advance(void)682 void Advance(void) { mItem = mItem->GetNext(); } 683 }; 684 685 Type *mHead; 686 }; 687 688 /** 689 * @} 690 * 691 */ 692 693 } // namespace ot 694 695 #endif // LINKED_LIST_HPP_ 696