Skip to content

Commit b5289bc

Browse files
committed
cpp: improve some comments
1 parent ac2d2f7 commit b5289bc

5 files changed

Lines changed: 304 additions & 336 deletions

File tree

‎cpp/algorithm.cpp‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ int main() {
241241
}
242242

243243

244-
// # max_element #min_element
244+
// # max_element
245+
//
246+
// # min_element
245247
{
246248
std::vector<int> v{2,0,1};
247249
assert(*std::max_element(v.begin(), v.end()) == 2);
@@ -279,4 +281,35 @@ int main() {
279281
assert(*itNext == 2);
280282
}
281283
#endif
284+
285+
// # remove_if
286+
//
287+
// Remove if a given function evaluates to true on an element.
288+
{
289+
{
290+
std::vector<int> v{0, 1, 2, 3, 4};
291+
auto end = v.end();
292+
v.erase(std::remove_if(v.begin(), end, odd), end);
293+
assert((v == std::vector<int>{0, 2, 4}));
294+
}
295+
296+
// Common combo with lambdas
297+
{
298+
std::vector<int> v{0, 1, 2, 3, 4};
299+
auto end = v.end();
300+
v.erase(std::remove_if(v.begin(), end,
301+
[](int i) {return i % 2 == 1;}), end);
302+
assert((v == std::vector<int>{0, 2, 4}));
303+
}
304+
}
305+
306+
// # transform
307+
//
308+
// Replace elements by output of a function.
309+
{
310+
std::vector<int> v{0, 1, 2};
311+
std::transform(v.begin(), v.end(), v.begin(),
312+
[](int i) {return i * i;});
313+
assert((v == std::vector<int>{0, 1, 4}));
314+
}
282315
}

‎cpp/implicitly_defined.cpp‎

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,41 @@
1-
// Implicitly defined functions
1+
// # Implicitly defined functions
22
//
3-
// https://stackoverflow.com/questions/12340257/default-vs-implicit-constructor-in-c
4-
// https://blog.mozilla.org/nfroyd/2015/08/20/explicit-is-better-than-implicit-c-implicitly-defined-member-functions/
5-
// https://stackoverflow.com/questions/3734247/what-are-all-the-member-functions-created-by-compiler-for-a-class-does-that-hap
6-
// https://stackoverflow.com/questions/4943958/conditions-for-automatic-generation-of-default-copy-move-ctor-and-copy-move-assi
7-
// https://en.cppreference.com/w/cpp/language/copy_constructor
8-
// https://en.cppreference.com/w/cpp/language/move_constructor
9-
// https://en.cppreference.com/w/cpp/language/copy_assignment
10-
// https://en.cppreference.com/w/cpp/language/move_assignment
3+
// - https://stackoverflow.com/questions/12340257/default-vs-implicit-constructor-in-c
4+
// - https://blog.mozilla.org/nfroyd/2015/08/20/explicit-is-better-than-implicit-c-implicitly-defined-member-functions/
5+
// - https://stackoverflow.com/questions/3734247/what-are-all-the-member-functions-created-by-compiler-for-a-class-does-that-hap
6+
// - https://stackoverflow.com/questions/4943958/conditions-for-automatic-generation-of-default-copy-move-ctor-and-copy-move-assi
7+
// - https://en.cppreference.com/w/cpp/language/copy_constructor
8+
// - https://en.cppreference.com/w/cpp/language/move_constructor
9+
// - https://en.cppreference.com/w/cpp/language/copy_assignment
10+
// - https://en.cppreference.com/w/cpp/language/move_assignment
1111

1212
#include "common.hpp"
1313

14+
struct Default {
15+
int i;
16+
Default() = default;
17+
Default(const Default&) = default;
18+
Default& operator=(Default&) = default;
19+
Default& operator=(const Default&) = default;
20+
Default(Default&&) = default;
21+
Default& operator=(Default&&) = default;
22+
~Default() = default;
23+
};
24+
25+
struct Instrument {
26+
int i;
27+
static std::vector<std::string> calls;
28+
Instrument() { calls.push_back("ctor"); }
29+
Instrument(const Instrument&) { calls.push_back("copy ctor"); }
30+
Instrument& operator=(Instrument&) { calls.push_back("copy assign"); return *this; }
31+
Instrument& operator=(const Instrument&) { calls.push_back("copy assign const"); return *this; }
32+
Instrument(Instrument&&) { calls.push_back("move ctor"); }
33+
Instrument& operator=(Instrument&&) { calls.push_back("move assign"); return *this; }
34+
~Instrument() { calls.push_back("dtor"); }
35+
};
36+
std::vector<std::string> Instrument::calls;
37+
1438
int main() {
15-
struct C {
16-
C() = default;
17-
C(const C&) = default;
18-
C& operator=(C&) = default;
19-
C& operator=(const C&) = default;
20-
C(C&&) = default;
21-
C& operator=(C&&) = default;
22-
~C() = default;
23-
};
39+
Instrument i;
40+
assert(Instrument::calls.back() == "ctor");
2441
}

‎cpp/map.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ int main() {
142142
}
143143
}
144144

145-
// # at()
145+
// # at
146146
//
147147
// A convenient version of find() that returns the item directly.
148148
//

‎cpp/set.cpp‎

Lines changed: 80 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
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

Comments
 (0)