xref: /aosp_15_r20/external/pigweed/pw_containers/intrusive_item_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2024 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include <cstdint>
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include "pw_compilation_testing/negative_compilation.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_forward_list.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_list.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_map.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_multimap.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_multiset.h"
23*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_set.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
25*61c4878aSAndroid Build Coastguard Worker 
26*61c4878aSAndroid Build Coastguard Worker namespace {
27*61c4878aSAndroid Build Coastguard Worker 
28*61c4878aSAndroid Build Coastguard Worker using pw::IntrusiveForwardList;
29*61c4878aSAndroid Build Coastguard Worker using pw::IntrusiveMap;
30*61c4878aSAndroid Build Coastguard Worker using pw::IntrusiveMultiMap;
31*61c4878aSAndroid Build Coastguard Worker using pw::IntrusiveMultiSet;
32*61c4878aSAndroid Build Coastguard Worker using pw::IntrusiveSet;
33*61c4878aSAndroid Build Coastguard Worker using pw::containers::future::IntrusiveList;
34*61c4878aSAndroid Build Coastguard Worker 
35*61c4878aSAndroid Build Coastguard Worker struct ForwardListItem1 : public IntrusiveForwardList<ForwardListItem1>::Item {
36*61c4878aSAndroid Build Coastguard Worker };
37*61c4878aSAndroid Build Coastguard Worker struct ForwardListItem2 : public IntrusiveForwardList<ForwardListItem2>::Item {
38*61c4878aSAndroid Build Coastguard Worker };
39*61c4878aSAndroid Build Coastguard Worker struct ListItem1 : public IntrusiveList<ListItem1>::Item {};
40*61c4878aSAndroid Build Coastguard Worker struct ListItem2 : public IntrusiveList<ListItem2>::Item {};
41*61c4878aSAndroid Build Coastguard Worker 
42*61c4878aSAndroid Build Coastguard Worker struct MapPair1 : public IntrusiveMap<uint32_t, MapPair1>::Pair {
MapPair1__anon2a4d2c500111::MapPair143*61c4878aSAndroid Build Coastguard Worker   explicit MapPair1(uint32_t id) : IntrusiveMap<uint32_t, MapPair1>::Pair(id) {}
44*61c4878aSAndroid Build Coastguard Worker };
45*61c4878aSAndroid Build Coastguard Worker struct MapPair2 : public IntrusiveMap<uint32_t, MapPair2>::Pair {
MapPair2__anon2a4d2c500111::MapPair246*61c4878aSAndroid Build Coastguard Worker   explicit MapPair2(uint32_t id) : IntrusiveMap<uint32_t, MapPair2>::Pair(id) {}
47*61c4878aSAndroid Build Coastguard Worker };
48*61c4878aSAndroid Build Coastguard Worker struct MultiMapPair1 : public IntrusiveMultiMap<uint32_t, MultiMapPair1>::Pair {
MultiMapPair1__anon2a4d2c500111::MultiMapPair149*61c4878aSAndroid Build Coastguard Worker   explicit MultiMapPair1(uint32_t id)
50*61c4878aSAndroid Build Coastguard Worker       : IntrusiveMultiMap<uint32_t, MultiMapPair1>::Pair(id) {}
51*61c4878aSAndroid Build Coastguard Worker };
52*61c4878aSAndroid Build Coastguard Worker struct MultiMapPair2 : public IntrusiveMultiMap<uint32_t, MultiMapPair2>::Pair {
MultiMapPair2__anon2a4d2c500111::MultiMapPair253*61c4878aSAndroid Build Coastguard Worker   explicit MultiMapPair2(uint32_t id)
54*61c4878aSAndroid Build Coastguard Worker       : IntrusiveMultiMap<uint32_t, MultiMapPair2>::Pair(id) {}
55*61c4878aSAndroid Build Coastguard Worker };
56*61c4878aSAndroid Build Coastguard Worker 
57*61c4878aSAndroid Build Coastguard Worker struct SetItem1 : public IntrusiveSet<SetItem1>::Item {
operator <__anon2a4d2c500111::SetItem158*61c4878aSAndroid Build Coastguard Worker   bool operator<(const SetItem1& rhs) const { return this < &rhs; }
59*61c4878aSAndroid Build Coastguard Worker };
60*61c4878aSAndroid Build Coastguard Worker struct SetItem2 : public IntrusiveSet<SetItem2>::Item {
operator <__anon2a4d2c500111::SetItem261*61c4878aSAndroid Build Coastguard Worker   bool operator<(const SetItem2& rhs) const { return this < &rhs; }
62*61c4878aSAndroid Build Coastguard Worker };
63*61c4878aSAndroid Build Coastguard Worker struct MultiSetItem1 : public IntrusiveMultiSet<MultiSetItem1>::Item {
operator <__anon2a4d2c500111::MultiSetItem164*61c4878aSAndroid Build Coastguard Worker   bool operator<(const MultiSetItem1& rhs) const { return this < &rhs; }
65*61c4878aSAndroid Build Coastguard Worker };
66*61c4878aSAndroid Build Coastguard Worker struct MultiSetItem2 : public IntrusiveMultiSet<MultiSetItem2>::Item {
operator <__anon2a4d2c500111::MultiSetItem267*61c4878aSAndroid Build Coastguard Worker   bool operator<(const MultiSetItem2& rhs) const { return this < &rhs; }
68*61c4878aSAndroid Build Coastguard Worker };
69*61c4878aSAndroid Build Coastguard Worker 
70*61c4878aSAndroid Build Coastguard Worker class Base {
71*61c4878aSAndroid Build Coastguard Worker  public:
Base(const char * name)72*61c4878aSAndroid Build Coastguard Worker   explicit constexpr Base(const char* name) : name_(name) {}
name() const73*61c4878aSAndroid Build Coastguard Worker   constexpr const char* name() const { return name_; }
74*61c4878aSAndroid Build Coastguard Worker 
75*61c4878aSAndroid Build Coastguard Worker  private:
76*61c4878aSAndroid Build Coastguard Worker   const char* name_;
77*61c4878aSAndroid Build Coastguard Worker };
78*61c4878aSAndroid Build Coastguard Worker 
79*61c4878aSAndroid Build Coastguard Worker class Derived : public Base,
80*61c4878aSAndroid Build Coastguard Worker                 public ForwardListItem1,
81*61c4878aSAndroid Build Coastguard Worker                 public ForwardListItem2,
82*61c4878aSAndroid Build Coastguard Worker                 public ListItem1,
83*61c4878aSAndroid Build Coastguard Worker                 public ListItem2,
84*61c4878aSAndroid Build Coastguard Worker                 public MapPair1,
85*61c4878aSAndroid Build Coastguard Worker                 public MapPair2,
86*61c4878aSAndroid Build Coastguard Worker                 public MultiMapPair1,
87*61c4878aSAndroid Build Coastguard Worker                 public MultiMapPair2,
88*61c4878aSAndroid Build Coastguard Worker                 public SetItem1,
89*61c4878aSAndroid Build Coastguard Worker                 public SetItem2,
90*61c4878aSAndroid Build Coastguard Worker                 public MultiSetItem1,
91*61c4878aSAndroid Build Coastguard Worker                 public MultiSetItem2 {
92*61c4878aSAndroid Build Coastguard Worker  public:
Derived(const char * name,uint32_t id)93*61c4878aSAndroid Build Coastguard Worker   Derived(const char* name, uint32_t id)
94*61c4878aSAndroid Build Coastguard Worker       : Base(name),
95*61c4878aSAndroid Build Coastguard Worker         MapPair1(id),
96*61c4878aSAndroid Build Coastguard Worker         MapPair2(id),
97*61c4878aSAndroid Build Coastguard Worker         MultiMapPair1(id),
98*61c4878aSAndroid Build Coastguard Worker         MultiMapPair2(id) {}
99*61c4878aSAndroid Build Coastguard Worker };
100*61c4878aSAndroid Build Coastguard Worker 
TEST(IntrusiveItemTest,AddToEachContainerSequentially)101*61c4878aSAndroid Build Coastguard Worker TEST(IntrusiveItemTest, AddToEachContainerSequentially) {
102*61c4878aSAndroid Build Coastguard Worker   Derived item("a", 1);
103*61c4878aSAndroid Build Coastguard Worker 
104*61c4878aSAndroid Build Coastguard Worker   IntrusiveForwardList<ForwardListItem1> forward_list1;
105*61c4878aSAndroid Build Coastguard Worker   IntrusiveForwardList<ForwardListItem2> forward_list2;
106*61c4878aSAndroid Build Coastguard Worker   IntrusiveList<ListItem1> list1;
107*61c4878aSAndroid Build Coastguard Worker   IntrusiveList<ListItem2> list2;
108*61c4878aSAndroid Build Coastguard Worker   IntrusiveMap<uint32_t, MapPair1> map1;
109*61c4878aSAndroid Build Coastguard Worker   IntrusiveMap<uint32_t, MapPair2> map2;
110*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap<uint32_t, MultiMapPair1> multimap1;
111*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap<uint32_t, MultiMapPair2> multimap2;
112*61c4878aSAndroid Build Coastguard Worker   IntrusiveSet<SetItem1> set1;
113*61c4878aSAndroid Build Coastguard Worker   IntrusiveSet<SetItem2> set2;
114*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiSet<MultiSetItem1> multiset1;
115*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiSet<MultiSetItem2> multiset2;
116*61c4878aSAndroid Build Coastguard Worker 
117*61c4878aSAndroid Build Coastguard Worker   forward_list1.push_front(item);
118*61c4878aSAndroid Build Coastguard Worker   forward_list1.clear();
119*61c4878aSAndroid Build Coastguard Worker 
120*61c4878aSAndroid Build Coastguard Worker   forward_list2.push_front(item);
121*61c4878aSAndroid Build Coastguard Worker   forward_list2.clear();
122*61c4878aSAndroid Build Coastguard Worker 
123*61c4878aSAndroid Build Coastguard Worker   list1.push_back(item);
124*61c4878aSAndroid Build Coastguard Worker   list1.clear();
125*61c4878aSAndroid Build Coastguard Worker 
126*61c4878aSAndroid Build Coastguard Worker   list2.push_back(item);
127*61c4878aSAndroid Build Coastguard Worker   list2.clear();
128*61c4878aSAndroid Build Coastguard Worker 
129*61c4878aSAndroid Build Coastguard Worker   map1.insert(item);
130*61c4878aSAndroid Build Coastguard Worker   map1.clear();
131*61c4878aSAndroid Build Coastguard Worker 
132*61c4878aSAndroid Build Coastguard Worker   map2.insert(item);
133*61c4878aSAndroid Build Coastguard Worker   map2.clear();
134*61c4878aSAndroid Build Coastguard Worker 
135*61c4878aSAndroid Build Coastguard Worker   multimap1.insert(item);
136*61c4878aSAndroid Build Coastguard Worker   multimap1.clear();
137*61c4878aSAndroid Build Coastguard Worker 
138*61c4878aSAndroid Build Coastguard Worker   multimap2.insert(item);
139*61c4878aSAndroid Build Coastguard Worker   multimap2.clear();
140*61c4878aSAndroid Build Coastguard Worker 
141*61c4878aSAndroid Build Coastguard Worker   set1.insert(item);
142*61c4878aSAndroid Build Coastguard Worker   set1.clear();
143*61c4878aSAndroid Build Coastguard Worker 
144*61c4878aSAndroid Build Coastguard Worker   set2.insert(item);
145*61c4878aSAndroid Build Coastguard Worker   set2.clear();
146*61c4878aSAndroid Build Coastguard Worker 
147*61c4878aSAndroid Build Coastguard Worker   multiset1.insert(item);
148*61c4878aSAndroid Build Coastguard Worker   multiset1.clear();
149*61c4878aSAndroid Build Coastguard Worker 
150*61c4878aSAndroid Build Coastguard Worker   multiset2.insert(item);
151*61c4878aSAndroid Build Coastguard Worker   multiset2.clear();
152*61c4878aSAndroid Build Coastguard Worker }
153*61c4878aSAndroid Build Coastguard Worker 
TEST(IntrusiveItemTest,AddToEachContainerSimultaneousy)154*61c4878aSAndroid Build Coastguard Worker TEST(IntrusiveItemTest, AddToEachContainerSimultaneousy) {
155*61c4878aSAndroid Build Coastguard Worker   Derived item("a", 1);
156*61c4878aSAndroid Build Coastguard Worker 
157*61c4878aSAndroid Build Coastguard Worker   IntrusiveForwardList<ForwardListItem1> forward_list1;
158*61c4878aSAndroid Build Coastguard Worker   IntrusiveForwardList<ForwardListItem2> forward_list2;
159*61c4878aSAndroid Build Coastguard Worker   IntrusiveList<ListItem1> list1;
160*61c4878aSAndroid Build Coastguard Worker   IntrusiveList<ListItem2> list2;
161*61c4878aSAndroid Build Coastguard Worker   IntrusiveMap<uint32_t, MapPair1> map1;
162*61c4878aSAndroid Build Coastguard Worker   IntrusiveMap<uint32_t, MapPair2> map2;
163*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap<uint32_t, MultiMapPair1> multimap1;
164*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap<uint32_t, MultiMapPair2> multimap2;
165*61c4878aSAndroid Build Coastguard Worker   IntrusiveSet<SetItem1> set1;
166*61c4878aSAndroid Build Coastguard Worker   IntrusiveSet<SetItem2> set2;
167*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiSet<MultiSetItem1> multiset1;
168*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiSet<MultiSetItem2> multiset2;
169*61c4878aSAndroid Build Coastguard Worker 
170*61c4878aSAndroid Build Coastguard Worker   forward_list1.push_front(item);
171*61c4878aSAndroid Build Coastguard Worker   list1.push_back(item);
172*61c4878aSAndroid Build Coastguard Worker   map1.insert(item);
173*61c4878aSAndroid Build Coastguard Worker   multimap1.insert(item);
174*61c4878aSAndroid Build Coastguard Worker   set1.insert(item);
175*61c4878aSAndroid Build Coastguard Worker   multiset1.insert(item);
176*61c4878aSAndroid Build Coastguard Worker 
177*61c4878aSAndroid Build Coastguard Worker   forward_list1.clear();
178*61c4878aSAndroid Build Coastguard Worker   list1.clear();
179*61c4878aSAndroid Build Coastguard Worker   map1.clear();
180*61c4878aSAndroid Build Coastguard Worker   multimap1.clear();
181*61c4878aSAndroid Build Coastguard Worker   set1.clear();
182*61c4878aSAndroid Build Coastguard Worker   multiset1.clear();
183*61c4878aSAndroid Build Coastguard Worker 
184*61c4878aSAndroid Build Coastguard Worker   forward_list2.push_front(item);
185*61c4878aSAndroid Build Coastguard Worker   list2.push_back(item);
186*61c4878aSAndroid Build Coastguard Worker   map2.insert(item);
187*61c4878aSAndroid Build Coastguard Worker   multimap2.insert(item);
188*61c4878aSAndroid Build Coastguard Worker   set2.insert(item);
189*61c4878aSAndroid Build Coastguard Worker   multiset2.insert(item);
190*61c4878aSAndroid Build Coastguard Worker 
191*61c4878aSAndroid Build Coastguard Worker   forward_list2.clear();
192*61c4878aSAndroid Build Coastguard Worker   list2.clear();
193*61c4878aSAndroid Build Coastguard Worker   map2.clear();
194*61c4878aSAndroid Build Coastguard Worker   multimap2.clear();
195*61c4878aSAndroid Build Coastguard Worker   set2.clear();
196*61c4878aSAndroid Build Coastguard Worker   multiset2.clear();
197*61c4878aSAndroid Build Coastguard Worker }
198*61c4878aSAndroid Build Coastguard Worker 
199*61c4878aSAndroid Build Coastguard Worker #if PW_NC_TEST(ForwardListValueTypeHasMultipleBases)
200*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
201*61c4878aSAndroid Build Coastguard Worker     "member 'ItemType' found in multiple base classes of different types");
202*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("lookup of 'ItemType' in '{anonymous}::Derived' is ambiguous");
203*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveForwardList<Derived> bad_fwd_list;
204*61c4878aSAndroid Build Coastguard Worker 
205*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(ListValueTypeHasMultipleBases)
206*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
207*61c4878aSAndroid Build Coastguard Worker     "member 'ItemType' found in multiple base classes of different types");
208*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("lookup of 'ItemType' in '{anonymous}::Derived' is ambiguous");
209*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveList<Derived> bad_list;
210*61c4878aSAndroid Build Coastguard Worker 
211*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(MapValueTypeHasMultipleBases)
212*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
213*61c4878aSAndroid Build Coastguard Worker     "member 'key' found in multiple base classes of different types");
214*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("request for member 'key' is ambiguous");
215*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveMap<uint32_t, Derived> bad_map;
216*61c4878aSAndroid Build Coastguard Worker 
217*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(MultiMapValueTypeHasMultipleBases)
218*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
219*61c4878aSAndroid Build Coastguard Worker     "member 'key' found in multiple base classes of different types");
220*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("request for member 'key' is ambiguous");
221*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveMultiMap<uint32_t, Derived> bad_multimap;
222*61c4878aSAndroid Build Coastguard Worker 
223*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(SetValueTypeHasMultipleBases)
224*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
225*61c4878aSAndroid Build Coastguard Worker     "member 'ItemType' found in multiple base classes of different types");
226*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("lookup of 'ItemType' in '{anonymous}::Derived' is ambiguous");
227*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveSet<Derived> bad_set([](const Derived& lhs,
__anon2a4d2c500202(const Derived& lhs, const Derived& rhs) 228*61c4878aSAndroid Build Coastguard Worker                                                   const Derived& rhs) {
229*61c4878aSAndroid Build Coastguard Worker   return &lhs < &rhs;
230*61c4878aSAndroid Build Coastguard Worker });
231*61c4878aSAndroid Build Coastguard Worker 
232*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(MultiSetValueTypeHasMultipleBases)
233*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_CLANG(
234*61c4878aSAndroid Build Coastguard Worker     "member 'ItemType' found in multiple base classes of different types");
235*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT_GCC("lookup of 'ItemType' in '{anonymous}::Derived' is ambiguous");
236*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] IntrusiveMultiSet<Derived> bad_multiset(
__anon2a4d2c500302(const Derived& lhs, const Derived& rhs) 237*61c4878aSAndroid Build Coastguard Worker     [](const Derived& lhs, const Derived& rhs) { return &lhs < &rhs; });
238*61c4878aSAndroid Build Coastguard Worker 
239*61c4878aSAndroid Build Coastguard Worker #endif  // PW_NC_TEST
240*61c4878aSAndroid Build Coastguard Worker 
241*61c4878aSAndroid Build Coastguard Worker }  // namespace
242