1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef DISTRIBUTEDDATAMGR_PASTEBOARD_LINKED_LIST_H
17 #define DISTRIBUTEDDATAMGR_PASTEBOARD_LINKED_LIST_H
18 
19 #include <functional>
20 #include <mutex>
21 
22 namespace OHOS {
23 namespace MiscServices {
24 
25 template <typename T>
26 struct ListNode {
27     explicit ListNode(const T &val = {}) : value(val), next(nullptr)
28     {
29     }
30 
31     T value;
32     ListNode<T> *next;
33 };
34 
35 template <typename T>
36 class LinkedList {
37 public:
LinkedList()38     LinkedList()
39     {
40         head_ = new ListNode<T>();
41     }
42 
~LinkedList()43     ~LinkedList()
44     {
45         Clear();
46         if (head_) {
47             delete head_;
48             head_ = nullptr;
49         }
50     }
51 
Clear()52     void Clear() noexcept
53     {
54         std::lock_guard<std::mutex> lock(mutex_);
55         if (head_ == nullptr) {
56             return;
57         }
58 
59         ListNode<T> *iter = head_->next;
60         ListNode<T> *next = nullptr;
61         while (iter) {
62             next = iter->next;
63             delete iter;
64             iter = next;
65         }
66         head_->next = nullptr;
67     }
68 
InsertFront(const T & value)69     void InsertFront(const T &value) noexcept
70     {
71         std::lock_guard<std::mutex> lock(mutex_);
72         if (head_ == nullptr) {
73             return;
74         }
75 
76         ListNode<T> *newNode = new ListNode<T>(value);
77         newNode->next = head_->next;
78         head_->next = newNode;
79     }
80 
InsertTail(const T & value)81     void InsertTail(const T &value) noexcept
82     {
83         std::lock_guard<std::mutex> lock(mutex_);
84         if (head_ == nullptr) {
85             return;
86         }
87 
88         ListNode<T> *newNode = new ListNode<T>(value);
89         ListNode<T> *iter = head_;
90         while (iter->next) {
91             iter = iter->next;
92         }
93         iter->next = newNode;
94     }
95 
RemoveIf(std::function<bool (const T &)> func)96     void RemoveIf(std::function<bool(const T&)> func) noexcept
97     {
98         std::lock_guard<std::mutex> lock(mutex_);
99         if (head_ == nullptr) {
100             return;
101         }
102 
103         ListNode<T> *iter = head_->next;
104         ListNode<T> *prev = head_;
105         while (iter) {
106             if (func(iter->value)) {
107                 prev->next = iter->next;
108                 delete iter;
109                 iter = prev->next;
110             } else {
111                 prev = iter;
112                 iter = iter->next;
113             }
114         }
115     }
116 
FindExist(const T & value)117     bool FindExist(const T &value) noexcept
118     {
119         std::lock_guard<std::mutex> lock(mutex_);
120         if (head_ == nullptr) {
121             return false;
122         }
123 
124         ListNode<T> *iter = head_->next;
125         while (iter) {
126             if (iter->value == value) {
127                 return true;
128             }
129             iter = iter->next;
130         }
131         return false;
132     }
133 
FindExist(std::function<bool (const T &)> func)134     bool FindExist(std::function<bool(const T&)> func) noexcept
135     {
136         std::lock_guard<std::mutex> lock(mutex_);
137         if (head_ == nullptr) {
138             return false;
139         }
140 
141         ListNode<T> *iter = head_->next;
142         while (iter) {
143             if (func(iter->value)) {
144                 return true;
145             }
146             iter = iter->next;
147         }
148         return false;
149     }
150 
ForEach(std::function<void (const T &)> func)151     void ForEach(std::function<void(const T&)> func) noexcept
152     {
153         std::lock_guard<std::mutex> lock(mutex_);
154         if (head_ == nullptr) {
155             return;
156         }
157 
158         ListNode<T> *iter = head_->next;
159         while (iter) {
160             func(iter->value);
161             iter = iter->next;
162         }
163     }
164 
165 private:
166     ListNode<T> *head_;
167     std::mutex mutex_;
168 };
169 } // namespace MiscServices
170 } // namespace OHOS
171 
172 #endif // DISTRIBUTEDDATAMGR_PASTEBOARD_LINKED_LIST_H
173 
174