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