Skip to content

Commit 92fa8c8

Browse files
committed
src: improve TSList iteration and erase operations
Add a size-aware for_each overload to TSList so callbacks can observe the list size while iterating. Return the updated size from erase and extend coverage for object and pointer specializations. Signed-off-by: Santiago Gimeno <santiago.gimeno@gmail.com> PR-URL: #517 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent ac28412 commit 92fa8c8

2 files changed

Lines changed: 98 additions & 2 deletions

File tree

src/nsolid/thread_safe.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,17 @@ struct TSList {
158158
nsuv::ns_mutex::scoped_lock lock(lock_);
159159
std::for_each(list_.begin(), list_.end(), fn);
160160
}
161-
inline void erase(iterator it) {
161+
inline void for_each(std::function<void(const DataType&, size_t)> fn) {
162+
nsuv::ns_mutex::scoped_lock lock(lock_);
163+
size_t current_size = list_.size();
164+
for (auto& item : list_) {
165+
fn(item, current_size);
166+
}
167+
}
168+
inline size_t erase(iterator it) {
162169
nsuv::ns_mutex::scoped_lock lock(lock_);
163170
list_.erase(it);
171+
return list_.size();
164172
}
165173
inline size_t size() {
166174
nsuv::ns_mutex::scoped_lock lock(lock_);
@@ -190,9 +198,17 @@ struct TSList<DataType*> {
190198
nsuv::ns_mutex::scoped_lock lock(lock_);
191199
std::for_each(list_.begin(), list_.end(), fn);
192200
}
193-
inline void erase(iterator it) {
201+
inline void for_each(std::function<void(DataType*, size_t)> fn) {
202+
nsuv::ns_mutex::scoped_lock lock(lock_);
203+
size_t current_size = list_.size();
204+
for (auto& item : list_) {
205+
fn(item, current_size);
206+
}
207+
}
208+
inline size_t erase(iterator it) {
194209
nsuv::ns_mutex::scoped_lock lock(lock_);
195210
list_.erase(it);
211+
return list_.size();
196212
}
197213
inline size_t size() {
198214
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+
list.push_back(10);
57+
list.push_back(20);
58+
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)