1 /* 2 * Copyright (c) 2021, 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 singly linked list which owns its entries and frees them upon destruction of 32 * the list. 33 */ 34 35 #ifndef OWNING_LIST_HPP_ 36 #define OWNING_LIST_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #include "common/linked_list.hpp" 41 #include "common/owned_ptr.hpp" 42 43 namespace ot { 44 45 /** 46 * Represents a singly linked list which owns its entries and frees them upon destruction of the 47 * list. 48 * 49 */ 50 template <typename Type> class OwningList : public LinkedList<Type> 51 { 52 class Iterator; 53 class ConstIterator; 54 55 public: 56 /** 57 * This is the default constructor for `OwningList` 58 * 59 */ 60 OwningList(void) = default; 61 62 /** 63 * This is the destructor for `OwningList`. 64 * 65 * On destruction, all existing entries in the list are freed. 66 * 67 */ ~OwningList(void)68 ~OwningList(void) { Free(); } 69 70 /** 71 * Clears the list and frees all existing entries in it. 72 * 73 */ Free(void)74 void Free(void) 75 { 76 while (!Pop().IsNull()) 77 { 78 } 79 } 80 81 /** 82 * Clears the list and frees all existing entries in it. 83 * 84 */ Clear(void)85 void Clear(void) { Free(); } 86 87 /** 88 * Pops an entry from head of the linked list and return an `OwnedPtr` to it. 89 * 90 * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before. 91 * 92 * @returns An `OwnedPtr` to the entry that was popped (set to null if list of empty). 93 * 94 */ Pop(void)95 OwnedPtr<Type> Pop(void) { return OwnedPtr<Type>(LinkedList<Type>::Pop()); } 96 97 /** 98 * Pops an entry after a given previous entry. 99 * 100 * @note This method does not change the popped entry itself, i.e., the popped entry next pointer stays as before. 101 * 102 * @param[in] aPrevEntry A pointer to a previous entry. If it is not `nullptr` the entry after this will be popped, 103 * otherwise (if it is `nullptr`) the entry at the head of the list is popped. 104 * 105 * @returns An `OwnedPtr` to the entry that was popped (set to null if there is no entry to pop). 106 * 107 */ PopAfter(Type * aPrevEntry)108 OwnedPtr<Type> PopAfter(Type *aPrevEntry) { return OwnedPtr<Type>(LinkedList<Type>::PopAfter(aPrevEntry)); } 109 110 /** 111 * Removes an entry matching a given entry indicator from the linked list. 112 * 113 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 114 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 115 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 116 * 117 * bool Type::Matches(const Indicator &aIndicator) const 118 * 119 * @note This method does not change the removed entry itself (which is returned in case of success), i.e., the 120 * entry next pointer stays as before. 121 * 122 * @param[in] aIndicator An entry indicator to match against entries in the list. 123 * 124 * @returns An `OwnedPtr` to the entry that was removed (set to null if there is no matching entry to remove). 125 * 126 */ RemoveMatching(const Indicator & aIndicator)127 template <typename Indicator> OwnedPtr<Type> RemoveMatching(const Indicator &aIndicator) 128 { 129 return OwnedPtr<Type>(LinkedList<Type>::RemoveMatching(aIndicator)); 130 } 131 132 /** 133 * Removes all entries in the list matching a given entry indicator from the list and adds 134 * them to a new list. 135 * 136 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 137 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 138 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 139 * 140 * bool Type::Matches(const Indicator &aIndicator) const 141 * 142 * The ownership of the removed entries is transferred from the original list to the @p aRemovedList. 143 * 144 * @param[in] aIndicator An entry indicator to match against entries in the list. 145 * @param[in] aRemovedList The list to add the removed entries to. 146 * 147 */ RemoveAllMatching(const Indicator & aIndicator,OwningList & aRemovedList)148 template <typename Indicator> void RemoveAllMatching(const Indicator &aIndicator, OwningList &aRemovedList) 149 { 150 LinkedList<Type>::RemoveAllMatching(aIndicator, aRemovedList); 151 } 152 153 /** 154 * Removes and frees all entries in the list matching a given entry indicator. 155 * 156 * The template type `Indicator` specifies the type of @p aIndicator object which is used to match against entries 157 * in the list. To check that an entry matches the given indicator, the `Matches()` method is invoked on each 158 * `Type` entry in the list. The `Matches()` method should be provided by `Type` class accordingly: 159 * 160 * bool Type::Matches(const Indicator &aIndicator) const 161 * 162 * @param[in] aIndicator An entry indicator to match against entries in the list. 163 * 164 * @retval TRUE At least one matching entry was removed. 165 * @retval FALSE No matching entry was found. 166 * 167 */ RemoveAndFreeAllMatching(const Indicator & aIndicator)168 template <typename Indicator> bool RemoveAndFreeAllMatching(const Indicator &aIndicator) 169 { 170 OwningList removedList; 171 172 RemoveAllMatching(aIndicator, removedList); 173 return !removedList.IsEmpty(); 174 } 175 }; 176 177 } // namespace ot 178 179 #endif // OWNING_LIST_HPP_ 180