Skip to content

Commit 455efa3

Browse files
committed
src: a couple of improvements in TSList API
Adds a for_each method to TSList that passes the current list size and item to the callback. Updates erase to return the new size after removal. These changes improve thread-safe iteration and management of hooks.
1 parent 2492fc8 commit 455efa3

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

src/nsolid/thread_safe.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,17 @@ struct TSList {
146146
nsuv::ns_mutex::scoped_lock lock(lock_);
147147
std::for_each(list_.begin(), list_.end(), fn);
148148
}
149-
inline void erase(iterator it) {
149+
inline void for_each(std::function<void(const DataType&, size_t)> fn) {
150+
nsuv::ns_mutex::scoped_lock lock(lock_);
151+
size_t current_size = list_.size();
152+
for (auto& item : list_) {
153+
fn(item, current_size);
154+
}
155+
}
156+
inline size_t erase(iterator it) {
150157
nsuv::ns_mutex::scoped_lock lock(lock_);
151158
list_.erase(it);
159+
return list_.size();
152160
}
153161
inline size_t size() {
154162
nsuv::ns_mutex::scoped_lock lock(lock_);
@@ -178,9 +186,17 @@ struct TSList<DataType*> {
178186
nsuv::ns_mutex::scoped_lock lock(lock_);
179187
std::for_each(list_.begin(), list_.end(), fn);
180188
}
181-
inline void erase(iterator it) {
189+
inline void for_each(std::function<void(DataType*, size_t)> fn) {
190+
nsuv::ns_mutex::scoped_lock lock(lock_);
191+
size_t current_size = list_.size();
192+
for (auto& item : list_) {
193+
fn(item, current_size);
194+
}
195+
}
196+
inline size_t erase(iterator it) {
182197
nsuv::ns_mutex::scoped_lock lock(lock_);
183198
list_.erase(it);
199+
return list_.size();
184200
}
185201
inline size_t size() {
186202
nsuv::ns_mutex::scoped_lock lock(lock_);

test/cctest/test_nsolid_thread_safe.cc

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,86 @@ TEST(TSListTest, ObjectIterator) {
5050
});
5151
}
5252

53+
// Test TSList::for_each with size parameter (object specialization)
54+
TEST(TSListTest, ObjectForEachWithSize) {
55+
TSList<int> list;
56+
auto it1 = list.push_back(10);
57+
auto it2 = list.push_back(20);
58+
auto it3 = list.push_back(30);
59+
std::vector<int> values;
60+
std::vector<size_t> sizes;
61+
list.for_each([&](const int& v, size_t size) {
62+
values.push_back(v);
63+
sizes.push_back(size);
64+
});
65+
EXPECT_EQ(values.size(), 3u);
66+
EXPECT_EQ(sizes[0], 3u);
67+
EXPECT_EQ(sizes[1], 3u);
68+
EXPECT_EQ(sizes[2], 3u);
69+
EXPECT_EQ(values[0], 10);
70+
EXPECT_EQ(values[1], 20);
71+
EXPECT_EQ(values[2], 30);
72+
}
73+
74+
// Test TSList::erase returns new size (object specialization)
75+
TEST(TSListTest, ObjectEraseReturnsSize) {
76+
TSList<int> list;
77+
auto it1 = list.push_back(1);
78+
auto it2 = list.push_back(2);
79+
auto it3 = list.push_back(3);
80+
EXPECT_EQ(list.erase(it2), 2u);
81+
EXPECT_EQ(list.erase(it1), 1u);
82+
EXPECT_EQ(list.erase(it3), 0u);
83+
}
84+
85+
// Test TSList::for_each with size parameter (pointer specialization)
86+
TEST(TSListTest, PointerForEachWithSize) {
87+
TSList<int*> list;
88+
auto it1 = list.push_back(new int(100));
89+
auto it2 = list.push_back(new int(200));
90+
auto it3 = list.push_back(new int(300));
91+
std::vector<int> values;
92+
std::vector<size_t> sizes;
93+
list.for_each([&](int* v, size_t size) {
94+
values.push_back(*v);
95+
sizes.push_back(size);
96+
});
97+
EXPECT_EQ(values.size(), 3u);
98+
EXPECT_EQ(sizes[0], 3u);
99+
EXPECT_EQ(sizes[1], 3u);
100+
EXPECT_EQ(sizes[2], 3u);
101+
EXPECT_EQ(values[0], 100);
102+
EXPECT_EQ(values[1], 200);
103+
EXPECT_EQ(values[2], 300);
104+
// Clean up
105+
int* tmp = *it1;
106+
delete tmp;
107+
tmp = *it2;
108+
delete tmp;
109+
tmp = *it3;
110+
delete tmp;
111+
list.erase(it1);
112+
list.erase(it2);
113+
list.erase(it3);
114+
}
115+
116+
// Test TSList::erase returns new size (pointer specialization)
117+
TEST(TSListTest, PointerEraseReturnsSize) {
118+
TSList<int*> list;
119+
auto it1 = list.push_back(new int(1));
120+
auto it2 = list.push_back(new int(2));
121+
auto it3 = list.push_back(new int(3));
122+
int* p1 = *it1;
123+
int* p2 = *it2;
124+
int* p3 = *it3;
125+
EXPECT_EQ(list.erase(it2), 2u);
126+
EXPECT_EQ(list.erase(it1), 1u);
127+
EXPECT_EQ(list.erase(it3), 0u);
128+
delete p1;
129+
delete p2;
130+
delete p3;
131+
}
132+
53133
TEST(TSListTest, PointerIterator) {
54134
TSList<int*> list;
55135
auto it1 = list.push_back(new int(1));

0 commit comments

Comments
 (0)