1- /*
2- # set
3-
4- Implemented with Red Black trees in GCC 6.4:
5- https://stackoverflow.com/questions/2558153/what-is-the-underlying-data-structure-of-a-stl-set-in-c/51944661#51944661
6-
7- A hashtable would be unlikely because it is sorted and can be efficiently iterated.
8-
9- Unique elements: inserting twice does nothing.
10-
11- Immutable elements: it is not possible to modify an object, one must first remove it and resinsert. This is so because modification may mean reordering.
12- */
1+ // # set
2+ //
3+ // Implemented with Red Black trees in GCC 6.4:
4+ // https://stackoverflow.com/questions/2558153/what-is-the-underlying-data-structure-of-a-stl-set-in-c/51944661#51944661
5+ //
6+ // A hashtable would be unlikely because it is sorted and can be efficiently iterated.
7+ //
8+ // Unique elements: inserting twice does nothing.
9+ //
10+ // Immutable elements: it is not possible to modify an object, one must first remove it and resinsert.
11+ // This is so because modification may mean reordering.
1312
1413#include " common.hpp"
1514
@@ -78,14 +77,12 @@ int main() {
7877 assert (i == 1 );
7978 }
8079
81- /*
82- # insert
83-
84- Return is a pair containing:
85-
86- - if the item was not present, an iterator to the item inserted and true
87- - if the item was present, an iterator to the existing item inserted and false
88- */
80+ // # insert
81+ //
82+ // Return is a pair containing:
83+ //
84+ // - if the item was not present, an iterator to the item inserted and true
85+ // - if the item was present, an iterator to the existing item inserted and false
8986 {
9087 std::pair<std::set<int ,std::string>::iterator,bool > ret;
9188 std::set<int > s;
@@ -112,13 +109,11 @@ int main() {
112109 assert (s == s1);
113110 }
114111
115- /*
116- # erase
117-
118- Remove element from set.
119-
120- Returns number of elements removed (either 0 or 1).
121- */
112+ // # erase
113+ //
114+ // Remove element from set.
115+ //
116+ // Returns number of elements removed (either 0 or 1).
122117 {
123118 std::set<int > s = {0 , 1 , 2 };
124119
@@ -142,20 +137,18 @@ int main() {
142137 assert (s.size () == 1 );
143138 }
144139
145- /*
146- iterate
147-
148- Biderectional iterator.
149-
150- Always sorted by key:
151- http://stackoverflow.com/questions/8833938/is-the-stdset-iteration-order-always-ascending-according-to-the-c-specificat/41424755#41424755
152-
153- This basically forces a balanced tree implementation instead of hash set,
154- and requires < > operators to be implemented on the value.
155-
156- Sorted by insertion order does not exist:
157- http://stackoverflow.com/questions/7801109/does-the-c-standard-library-have-a-set-ordered-by-insertion-order
158- */
140+ // # iterate
141+ //
142+ // Biderectional iterator.
143+ //
144+ // Always sorted by key:
145+ // http://stackoverflow.com/questions/8833938/is-the-stdset-iteration-order-always-ascending-according-to-the-c-specificat/41424755#41424755
146+ //
147+ // This basically forces a balanced tree implementation instead of hash set,
148+ // and requires < > operators to be implemented on the value.
149+ //
150+ // Sorted by insertion order does not exist:
151+ // http://stackoverflow.com/questions/7801109/does-the-c-standard-library-have-a-set-ordered-by-insertion-order
159152 {
160153 std::set<int > s;
161154 s.insert (2 );
@@ -168,14 +161,12 @@ int main() {
168161 assert (it == s.end ());
169162 }
170163
171- /*
172- # find
173-
174- If found, returns an iterator pointing to the element.
175- Else, returns `map::end()`
176-
177- find is `log n` time since the container is ordered.
178- */
164+ // # find
165+ //
166+ // If found, returns an iterator pointing to the element.
167+ // Else, returns `map::end()`
168+ //
169+ // find is `log n` time since the container is ordered.
179170 {
180171 std::set<int > s = {0 , 1 , 2 };
181172 std::set<int >::iterator it;
@@ -187,45 +178,39 @@ int main() {
187178 assert (it == s.end ());
188179 }
189180
190- /*
191- count
192-
193- Count how many times an item is in the set.
194-
195- Can only return 1 or 0.
196-
197- Equivalent to doing a find.
198- */
181+ // # count
182+ //
183+ // Count how many times an item is in the set.
184+ //
185+ // Can only return 1 or 0.
186+ //
187+ // Equivalent to doing a find.
199188 {
200189 std::set<int > s = {1 , 2 , 0 , 1 };
201190 assert (s.count (1 ) == 1 );
202191 assert (s.count (3 ) == 0 );
203192 }
204193
205- /*
206- # Modify key.
207-
208- # Update
209-
210- Impossible without either:
211-
212- - remove and re-insert (possibly with hint), which is the right way
213- - hacks like `mutable`
214-
215- Because `std::set<X>::iterator` is actually `const` by the standard:
216-
217- - http://stackoverflow.com/questions/908949/what-happens-when-you-modify-an-element-of-an-stdset
218- - http://stackoverflow.com/questions/2217878/c-stl-set-update-is-tedious-i-cant-change-an-element-in-place
219- - http://stackoverflow.com/questions/7340434/how-to-update-an-existing-element-of-stdset
220- - http://stackoverflow.com/questions/6068167/is-this-safe-mutability-and-sets
221-
222- # Hint
223-
224- If an iterator is given, it serves as a hint to where the new value is likely to be inserted.
225-
226- This is speciall useful if you want to update a value,
227- but expect the new result to be in the same position.
228- */
194+ // # Modify a key
195+ //
196+ // Impossible without either:
197+ //
198+ // - remove and re-insert (possibly with hint), which is the right way
199+ // - hacks like `mutable`
200+ //
201+ // Because `std::set<X>::iterator` is actually `const` by the standard:
202+ //
203+ // - http://stackoverflow.com/questions/908949/what-happens-when-you-modify-an-element-of-an-stdset
204+ // - http://stackoverflow.com/questions/2217878/c-stl-set-update-is-tedious-i-cant-change-an-element-in-place
205+ // - http://stackoverflow.com/questions/7340434/how-to-update-an-existing-element-of-stdset
206+ // - http://stackoverflow.com/questions/6068167/is-this-safe-mutability-and-sets
207+ //
208+ // # Hint
209+ //
210+ // If an iterator is given, it serves as a hint to where the new value is likely to be inserted.
211+ //
212+ // This is speciall useful if you want to update a value,
213+ // but expect the new result to be in the same position.
229214 {
230215 class C {
231216 public:
@@ -245,6 +230,7 @@ int main() {
245230 }
246231
247232 // Search by non-key comparable
233+ //
248234 // - http://stackoverflow.com/questions/17375780/is-it-possible-to-use-elements-of-a-different-type-than-contained-in-a-stdset
249235 // - http://stackoverflow.com/questions/20317413/what-are-transparent-comparators
250236 {
@@ -264,21 +250,24 @@ int main() {
264250 }
265251
266252 // unique_ptr
253+ //
267254 // - http://stackoverflow.com/questions/18939882/raw-pointer-lookup-for-sets-of-unique-ptrs
268255 // - http://stackoverflow.com/questions/17851088/using-a-stdunordered-set-of-stdunique-ptr
269256 {
257+ #if 0
270258 // Less good solution with a hidden operator<.
271259 {
272- // std::set<std::unique_ptr<MemberKey>, std::less<>> s;
273- // s.insert(std::make_unique<MemberKey>(1, -1));
274- // s.insert(std::make_unique<MemberKey>(2, -2));
275- // s.insert(std::make_unique<MemberKey>(0, 0));
276- // s.insert(std::make_unique<MemberKey>(3, -3));
277- // assert((*s.find(0))->notkey == 0);
278- // assert((*s.find(1))->notkey == -1);
279- // assert((*s.find(2))->notkey == -2);
280- // assert((*s.find(3))->notkey == -3);
260+ std::set<std::unique_ptr<MemberKey>, std::less<>> s;
261+ s.insert(std::make_unique<MemberKey>(1, -1));
262+ s.insert(std::make_unique<MemberKey>(2, -2));
263+ s.insert(std::make_unique<MemberKey>(0, 0));
264+ s.insert(std::make_unique<MemberKey>(3, -3));
265+ assert((*s.find(0))->notkey == 0);
266+ assert((*s.find(1))->notkey == -1);
267+ assert((*s.find(2))->notkey == -2);
268+ assert((*s.find(3))->notkey == -3);
281269 }
270+ #endif
282271
283272 // Better solution with a custom comparator.
284273 {
0 commit comments