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  * This template class represents a linked list entry.
59  *
60  * This class 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      * This method 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      * This method 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      * This method 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  * This template class 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      * This constructor initializes the linked list.
112      *
113      */
LinkedList(void)114     LinkedList(void)
115         : mHead(nullptr)
116     {
117     }
118 
119     /**
120      * This method 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      * This method 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      * This method 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      * This method clears the linked list.
145      *
146      */
Clear(void)147     void Clear(void) { mHead = nullptr; }
148 
149     /**
150      * This method 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      * This method 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      * This method 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      * This method pops an entry from head of the linked list.
185      *
186      * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before.
187      *
188      * @returns The entry that was popped if the list is not empty, or `nullptr` if the list is empty.
189      *
190      */
Pop(void)191     Type *Pop(void)
192     {
193         Type *entry = mHead;
194 
195         if (mHead != nullptr)
196         {
197             mHead = mHead->GetNext();
198         }
199 
200         return entry;
201     }
202 
203     /**
204      * This method pops an entry after a given previous entry.
205      *
206      * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before.
207      *
208      * @param[in] aPrevEntry  A pointer to a previous entry. If it is not `nullptr` the entry after this will be popped,
209      *                        otherwise (if it is `nullptr`) the entry at the head of the list is popped.
210      *
211      * @returns Pointer to the entry that was popped, or `nullptr` if there is no entry to pop.
212      *
213      */
PopAfter(Type * aPrevEntry)214     Type *PopAfter(Type *aPrevEntry)
215     {
216         Type *entry;
217 
218         if (aPrevEntry == nullptr)
219         {
220             entry = Pop();
221         }
222         else
223         {
224             entry = aPrevEntry->GetNext();
225 
226             if (entry != nullptr)
227             {
228                 aPrevEntry->SetNext(entry->GetNext());
229             }
230         }
231 
232         return entry;
233     }
234 
235     /**
236      * This method indicates whether the linked list contains a given entry.
237      *
238      * @param[in] aEntry   A reference to an entry.
239      *
240      * @retval TRUE   The linked list contains @p aEntry.
241      * @retval FALSE  The linked list does not contain @p aEntry.
242      *
243      */
Contains(const Type & aEntry) const244     bool Contains(const Type &aEntry) const
245     {
246         const Type *prev;
247 
248         return Find(aEntry, prev) == kErrorNone;
249     }
250 
251     /**
252      * This template method indicates whether the linked list contains an entry matching a given entry indicator.
253      *
254      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
255      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
256      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
257      *
258      *     bool Type::Matches(const Indicator &aIndicator) const
259      *
260      * @param[in] aIndicator   An entry indicator to match against entries in the list.
261      *
262      * @retval TRUE   The linked list contains an entry matching @p aIndicator.
263      * @retval FALSE  The linked list contains no entry matching @p aIndicator.
264      *
265      */
ContainsMatching(const Indicator & aIndicator) const266     template <typename Indicator> bool ContainsMatching(const Indicator &aIndicator) const
267     {
268         return FindMatching(aIndicator) != nullptr;
269     }
270 
271     /**
272      * This method adds an entry (at the head of the linked list) if it is not already in the list.
273      *
274      * @param[in] aEntry   A reference to an entry to add.
275      *
276      * @retval kErrorNone     The entry was successfully added at the head of the list.
277      * @retval kErrorAlready  The entry is already in the list.
278      *
279      */
Add(Type & aEntry)280     Error Add(Type &aEntry)
281     {
282         Error error = kErrorNone;
283 
284         if (Contains(aEntry))
285         {
286             error = kErrorAlready;
287         }
288         else
289         {
290             Push(aEntry);
291         }
292 
293         return error;
294     }
295 
296     /**
297      * This method removes an entry from the linked list.
298      *
299      * @note This method does not change the removed entry @p aEntry itself (it is `const`), i.e., the entry next
300      * pointer of @p aEntry stays as before.
301      *
302      * @param[in] aEntry   A reference to an entry to remove.
303      *
304      * @retval kErrorNone      The entry was successfully removed from the list.
305      * @retval kErrorNotFound  Could not find the entry in the list.
306      *
307      */
Remove(const Type & aEntry)308     Error Remove(const Type &aEntry)
309     {
310         Type *prev;
311         Error error = Find(aEntry, prev);
312 
313         if (error == kErrorNone)
314         {
315             PopAfter(prev);
316         }
317 
318         return error;
319     }
320 
321     /**
322      * This template method removes an entry matching a given entry indicator from the linked list.
323      *
324      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
325      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
326      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
327      *
328      *     bool Type::Matches(const Indicator &aIndicator) const
329      *
330      * @note This method does not change the removed entry itself (which is returned in case of success), i.e., the
331      * entry next pointer stays as before.
332      *
333      *
334      * @param[in] aIndicator   An entry indicator to match against entries in the list.
335      *
336      * @returns A pointer to the removed matching entry if one could be found, or `nullptr` if no matching entry is
337      *          found.
338      *
339      */
RemoveMatching(const Indicator & aIndicator)340     template <typename Indicator> Type *RemoveMatching(const Indicator &aIndicator)
341     {
342         Type *prev;
343         Type *entry = FindMatching(aIndicator, prev);
344 
345         if (entry != nullptr)
346         {
347             PopAfter(prev);
348         }
349 
350         return entry;
351     }
352 
353     /**
354      * This template method removes all entries in the list matching a given entry indicator from the list and adds
355      * them to a new list.
356      *
357      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
358      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
359      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
360      *
361      *     bool Type::Matches(const Indicator &aIndicator) const
362      *
363      * @param[in] aIndicator   An entry indicator to match against entries in the list.
364      * @param[in] aRemovedList The list to add the removed entries to.
365      *
366      */
RemoveAllMatching(const Indicator & aIndicator,LinkedList & aRemovedList)367     template <typename Indicator> void RemoveAllMatching(const Indicator &aIndicator, LinkedList &aRemovedList)
368     {
369         Type *entry;
370         Type *prev;
371         Type *next;
372 
373         for (prev = nullptr, entry = GetHead(); entry != nullptr; entry = next)
374         {
375             next = entry->GetNext();
376 
377             if (entry->Matches(aIndicator))
378             {
379                 PopAfter(prev);
380                 aRemovedList.Push(*entry);
381 
382                 // When the entry is removed from the list
383                 // we keep the `prev` pointer same as before.
384             }
385             else
386             {
387                 prev = entry;
388             }
389         }
390     }
391 
392     /**
393      * This method searches within the linked list to find an entry and if found returns a pointer to previous entry.
394      *
395      * @param[in]  aEntry      A reference to an entry to find.
396      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when @p aEntry is found in the list).
397      *                         @p aPrevEntry is set to `nullptr` if @p aEntry is the head of the list. Otherwise it is
398      *                         updated to point to the previous entry before @p aEntry in the list.
399      *
400      * @retval kErrorNone      The entry was found in the list and @p aPrevEntry was updated successfully.
401      * @retval kErrorNotFound  The entry was not found in the list.
402      *
403      */
Find(const Type & aEntry,const Type * & aPrevEntry) const404     Error Find(const Type &aEntry, const Type *&aPrevEntry) const
405     {
406         Error error = kErrorNotFound;
407 
408         aPrevEntry = nullptr;
409 
410         for (const Type *entry = mHead; entry != nullptr; aPrevEntry = entry, entry = entry->GetNext())
411         {
412             if (entry == &aEntry)
413             {
414                 error = kErrorNone;
415                 break;
416             }
417         }
418 
419         return error;
420     }
421 
422     /**
423      * This method searches within the linked list to find an entry and if found returns a pointer to previous entry.
424      *
425      * @param[in]  aEntry      A reference to an entry to find.
426      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when @p aEntry is found in the list).
427      *                         @p aPrevEntry is set to `nullptr` if @p aEntry is the head of the list. Otherwise it is
428      *                         updated to point to the previous entry before @p aEntry in the list.
429      *
430      * @retval kErrorNone      The entry was found in the list and @p aPrevEntry was updated successfully.
431      * @retval kErrorNotFound  The entry was not found in the list.
432      *
433      */
Find(const Type & aEntry,Type * & aPrevEntry)434     Error Find(const Type &aEntry, Type *&aPrevEntry)
435     {
436         return AsConst(this)->Find(aEntry, const_cast<const Type *&>(aPrevEntry));
437     }
438 
439     /**
440      * This template method searches within a given range of the linked list to find an entry matching a given
441      * indicator.
442      *
443      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
444      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
445      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
446      *
447      *     bool Type::Matches(const Indicator &aIndicator) const
448      *
449      * @param[in]  aBegin      A pointer to the begin of the range.
450      * @param[in]  aEnd        A pointer to the end of the range, or `nullptr` to search all entries after @p aBegin.
451      * @param[in]  aIndicator  An indicator to match with entries in the list.
452      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
453      *                         @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list.
454      *                         Otherwise it is updated to point to the previous entry before the matching entry in the
455      *                         list.
456      *
457      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
458      *
459      */
460     template <typename Indicator>
FindMatching(const Type * aBegin,const Type * aEnd,const Indicator & aIndicator,const Type * & aPrevEntry) const461     const Type *FindMatching(const Type      *aBegin,
462                              const Type      *aEnd,
463                              const Indicator &aIndicator,
464                              const Type     *&aPrevEntry) const
465     {
466         const Type *entry;
467 
468         aPrevEntry = nullptr;
469 
470         for (entry = aBegin; entry != aEnd; aPrevEntry = entry, entry = entry->GetNext())
471         {
472             if (entry->Matches(aIndicator))
473             {
474                 break;
475             }
476         }
477 
478         return entry;
479     }
480 
481     /**
482      * This template method searches within a given range of the linked list to find an entry matching a given
483      * indicator.
484      *
485      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
486      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
487      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
488      *
489      *     bool Type::Matches(const Indicator &aIndicator) const
490      *
491      * @param[in]  aBegin      A pointer to the begin of the range.
492      * @param[in]  aEnd        A pointer to the end of the range, or `nullptr` to search all entries after @p aBegin.
493      * @param[in]  aIndicator  An indicator to match with entries in the list.
494      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
495      *                         @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list.
496      *                         Otherwise it is updated to point to the previous entry before the matching entry in the
497      *                         list.
498      *
499      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
500      *
501      */
502     template <typename Indicator>
FindMatching(const Type * aBegin,const Type * aEnd,const Indicator & aIndicator,Type * & aPrevEntry)503     Type *FindMatching(const Type *aBegin, const Type *aEnd, const Indicator &aIndicator, Type *&aPrevEntry)
504     {
505         return AsNonConst(FindMatching(aBegin, aEnd, aIndicator, const_cast<const Type *&>(aPrevEntry)));
506     }
507 
508     /**
509      * This template method searches within the linked list to find an entry matching a given indicator.
510      *
511      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
512      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
513      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
514      *
515      *     bool Type::Matches(const Indicator &aIndicator) const
516      *
517      * @param[in]  aIndicator  An indicator to match with entries in the list.
518      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
519      *                         @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list.
520      *                         Otherwise it is updated to point to the previous entry before the matching entry in the
521      *                         list.
522      *
523      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
524      *
525      */
FindMatching(const Indicator & aIndicator,const Type * & aPrevEntry) const526     template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator, const Type *&aPrevEntry) const
527     {
528         return FindMatching(mHead, nullptr, aIndicator, aPrevEntry);
529     }
530 
531     /**
532      * This template method searches within the linked list to find an entry matching a given indicator, and if found
533      * returns a pointer to its previous entry in the list.
534      *
535      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
536      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
537      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
538      *
539      *     bool Type::Matches(const Indicator &aIndicator) const
540      *
541      * @param[in]  aIndicator  An indicator to match with entries in the list.
542      * @param[out] aPrevEntry  A pointer to output the previous entry on success (when a match is found in the list).
543      *                         @p aPrevEntry is set to `nullptr` if the matching entry is the head of the list.
544      *                         Otherwise it is updated to point to the previous entry before the matching entry in the
545      *                         list.
546      *
547      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
548      *
549      */
FindMatching(const Indicator & aIndicator,Type * & aPrevEntry)550     template <typename Indicator> Type *FindMatching(const Indicator &aIndicator, Type *&aPrevEntry)
551     {
552         return AsNonConst(AsConst(this)->FindMatching(aIndicator, const_cast<const Type *&>(aPrevEntry)));
553     }
554 
555     /**
556      * This template method searches within the linked list to find an entry matching a given indicator.
557      *
558      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
559      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
560      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
561      *
562      *     bool Type::Matches(const Indicator &aIndicator) const
563      *
564      * @param[in]  aIndicator  An indicator to match with entries in the list.
565      *
566      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
567      *
568      */
FindMatching(const Indicator & aIndicator) const569     template <typename Indicator> const Type *FindMatching(const Indicator &aIndicator) const
570     {
571         const Type *prev;
572 
573         return FindMatching(aIndicator, prev);
574     }
575 
576     /**
577      * This template method searches within the linked list to find an entry matching a given indicator.
578      *
579      * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries
580      * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each
581      * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly:
582      *
583      *     bool Type::Matches(const Indicator &aIndicator) const
584      *
585      * @param[in]  aIndicator  An indicator to match with entries in the list.
586      *
587      * @returns A pointer to the matching entry if one is found, or `nullptr` if no matching entry was found.
588      *
589      */
FindMatching(const Indicator & aIndicator)590     template <typename Indicator> Type *FindMatching(const Indicator &aIndicator)
591     {
592         return AsNonConst(AsConst(this)->FindMatching(aIndicator));
593     }
594 
595     /**
596      * This method returns the tail of the linked list (i.e., the last entry in the list).
597      *
598      * @returns A pointer to the tail entry in the linked list or `nullptr` if the list is empty.
599      *
600      */
GetTail(void) const601     const Type *GetTail(void) const
602     {
603         const Type *tail = mHead;
604 
605         if (tail != nullptr)
606         {
607             while (tail->GetNext() != nullptr)
608             {
609                 tail = tail->GetNext();
610             }
611         }
612 
613         return tail;
614     }
615 
616     /**
617      * This method returns the tail of the linked list (i.e., the last entry in the list).
618      *
619      * @returns A pointer to the tail entry in the linked list or `nullptr` if the list is empty.
620      *
621      */
GetTail(void)622     Type *GetTail(void) { return AsNonConst(AsConst(this)->GetTail()); }
623 
624     // The following methods are intended to support range-based `for`
625     // loop iteration over the linked-list entries and should not be
626     // used directly.
627 
begin(void)628     Iterator begin(void) { return Iterator(GetHead()); }
end(void)629     Iterator end(void) { return Iterator(nullptr); }
630 
begin(void) const631     ConstIterator begin(void) const { return ConstIterator(GetHead()); }
end(void) const632     ConstIterator end(void) const { return ConstIterator(nullptr); }
633 
634 private:
635     class Iterator : public ItemPtrIterator<Type, Iterator>
636     {
637         friend class LinkedList;
638         friend class ItemPtrIterator<Type, Iterator>;
639 
640         using ItemPtrIterator<Type, Iterator>::mItem;
641 
Iterator(Type * aItem)642         explicit Iterator(Type *aItem)
643             : ItemPtrIterator<Type, Iterator>(aItem)
644         {
645         }
646 
Advance(void)647         void Advance(void) { mItem = mItem->GetNext(); }
648     };
649 
650     class ConstIterator : public ItemPtrIterator<const Type, ConstIterator>
651     {
652         friend class LinkedList;
653         friend class ItemPtrIterator<const Type, ConstIterator>;
654 
655         using ItemPtrIterator<const Type, ConstIterator>::mItem;
656 
ConstIterator(const Type * aItem)657         explicit ConstIterator(const Type *aItem)
658             : ItemPtrIterator<const Type, ConstIterator>(aItem)
659         {
660         }
661 
Advance(void)662         void Advance(void) { mItem = mItem->GetNext(); }
663     };
664 
665     Type *mHead;
666 };
667 
668 /**
669  * @}
670  *
671  */
672 
673 } // namespace ot
674 
675 #endif // LINKED_LIST_HPP_
676