The original idea of this talk is that diversity in data structures and algorithms results in generic solutions being quirky and not universal (the irregularity conjecture).
To get there, we're going to have a bit of fun with simple data structures (linked lists) and simple algorithms (linear find and partition), see what (C++20) concepts are, to build towards the more philosophical part on the design and usage of generic code.
Mircea Baja @ ACCU Oxford - 26 Feb 2020
The original idea of this talk is that diversity in data structures and algorithms results in generic solutions being quirky and not universal (the irregularity conjecture).
To get there, we're going to have a bit of fun with simple data structures (linked lists) and simple algorithms (linear find and partition), see what (C++20) concepts are, to build towards the more philosophical part on the design and usage of generic code.
Theorem: the vector is just a kind of vector (paraphrasing Alex Stepanov)
Lemma: a linked list is just a kind of linked list
Use vectors, i.e. contiguous, extent based data structures
push_back()
std::forward_list
push_back()
std::list
in Visual C++ 2017/2019static_assert(std::is_nothrow_default_constructible_v<std::list<int>>, "Default constructor may throw");static_assert(std::is_nothrow_move_constructible_v<std::list<int>>, "Move constructor may throw");// both assert in Visual C++ 2017/2019
move
invalidates endstd::list
implementation option gcc/clangpush_back()
either: iterator not
minimalistic OR header not minimalistictemplate<typename T>class dl_list { struct node; struct links { node * next_; node * prev_; }; struct node : public links { T value_; //...
std::list
and std::forward_list
std::shared_ptr
and std::unique_ptr
int data[] = {2, 5, 7, 1, 22};int * it = find(std::begin(data), std::end(data), 5);if (it == std::end(data)) { // not found ...}else { // found ... *it = 42;}
int * find(int * f, int * l, int x) { while ((f != l) && (*f != x)) ++f; return f;}
find
and outside!=
, the other time with ==
template<typename It, typename T>It find(It f, It l, const T & x) { while ((f != l) && (*f != x)) ++f; return f;}
T
being int
, short
, long
, unsigned
etc.It
is pointer-like first
and last
to sequences of integer-like values
(e.g. T *
)It
can also be an iterator in a linked listf
and l
f
f
is reference to the value typef
(with ++
)f
equals l
, it stays that way, we can compare again and get the same
resultf
l
from f
, l
should not be dereferencedtemplate<typename It>using ValueType = typename It::value_type;template<typename It>concept InputIterator = requires(It a, It b){ {a == b} -> std::boolean; {a != b} -> std::boolean; typename ValueType<It>; {*a} -> std::common_reference_with<ValueType<It>>; ++a;};template<typename It> requires InputIterator<It>It find(It f, It l, const ValueType<It> & x){ while ((f != l) && (*f != x)) ++f; return f;}
template<InputIterator I, Sentinel<I> S, class T, class Proj = ranges::identity > requires IndirectRelation<ranges::equal_to<>, projected<I, Proj>, const T*>I find(I f, S l, const T& x, Proj proj = Proj{}){ while ((f != l) && (ranges::invoke(proj, *f) != x)) ++f; return f;}
T
is not necessarily the value type of the iteratorrange
e.g. the whole containerstd::cout << std::find(people, "Alice", &person::first_name)->last_name;
template<typename I, typename T>// requires I is an ForwardIterator// T is equality comparable,// T is the same as ValueType(I)I find_by_setting_sentinel(I f, I l, const T & v) { // precondition: l can be dereferenced to store value as sentinel *l = v; while (*f != v) { ++f; } return f;}
std::begin
Some a;a = b;assert(a == b);c = b;assert(a == c);
std::list
std::list
==
not !=
==
is different from not !=
push_back()
won't throw: vector
was previously resized![]() |
![]() |
![]() |
![]() |
Alexander A. Stepanov and Paul McJones: Elements of Programming
Robert Endre Tarjan: Data Structures and Network Algorithms
Andrew Sutton and Bjarne Stroustrup: Design of Concept Libraries for C++ SLE2011
https://bajamircea.github.io/coding/cpp/2018/08/01/linear-find.html
https://bajamircea.github.io/coding/cpp/2018/08/05/partition.html
https://bajamircea.github.io/coding/cpp/2018/06/28/linked-lists-examples.html
https://bajamircea.github.io/coding/cpp/2018/06/30/lists-implementing.html
https://bajamircea.github.io/presentations/2020-02-26-irregularity.html
Thanks go to Nigel Lester for organizing the ACCU meeting
Theorem: the vector is just a kind of vector (paraphrasing Alex Stepanov)
Lemma: a linked list is just a kind of linked list
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |