Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use...
Transcript of Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use...
![Page 1: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/1.jpg)
c© 2009 Andrei Alexandrescu 1 / 52
Iterators Must Go
Andrei Alexandrescu
![Page 2: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/2.jpg)
This Talk
c© 2009 Andrei Alexandrescu 2 / 52
• The STL
• Iterators
• Range-based design
• Conclusions
![Page 3: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/3.jpg)
What is the STL?
c© 2009 Andrei Alexandrescu 3 / 52
![Page 4: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/4.jpg)
Yeah, what is the STL?
c© 2009 Andrei Alexandrescu 4 / 52
• A good library of algorithms and data structures.
![Page 5: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/5.jpg)
Yeah, what is the STL?
c© 2009 Andrei Alexandrescu 4 / 52
• A ( good|bad) library of algorithms and data structures.
![Page 6: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/6.jpg)
Yeah, what is the STL?
c© 2009 Andrei Alexandrescu 4 / 52
• A ( good|bad|ugly) library of algorithms and datastructures.
![Page 7: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/7.jpg)
Yeah, what is the STL?
c© 2009 Andrei Alexandrescu 4 / 52
• A ( good|bad|ugly) library of algorithms and datastructures.
• iterators = gcd(containers, algorithms);
![Page 8: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/8.jpg)
Yeah, what is the STL?
c© 2009 Andrei Alexandrescu 4 / 52
• A ( good|bad|ugly) library of algorithms and datastructures.
• iterators = gcd(containers, algorithms);
• Scrumptious Template Lore
• Snout to Tail Length
![Page 9: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/9.jpg)
What the STL is
c© 2009 Andrei Alexandrescu 5 / 52
• More than the answer, the question is important in theSTL
• “What would the most general implementations offundamental containers and algorithms look like?”
• Everything else is aftermath
• Most importantly: STL is one answer, not the answer
![Page 11: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/11.jpg)
STL is nonintuitive
c© 2009 Andrei Alexandrescu 6 / 52
• Same way the theory of relativity is nonintuitive
• Same way complex numbers are nonintuitive (seee.g. xkcd.com)
![Page 12: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/12.jpg)
Nonintuitive
c© 2009 Andrei Alexandrescu 7 / 52
• “I want to design the most general algorithms.”
• “Sure. What you obviously need is something callediterators. Five of ’em, to be precise.”
![Page 13: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/13.jpg)
Nonintuitive
c© 2009 Andrei Alexandrescu 7 / 52
• “I want to design the most general algorithms.”
• “Sure. What you obviously need is something callediterators. Five of ’em, to be precise.”
• Evidence: No language has supported the STL “bychance.”
◦ In spite of relentless “feature wars”
◦ C++, D the only ones
◦ Both were actively designed to support the STL
• Consequence: STL very hard to understand fromoutside C++ or D
![Page 14: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/14.jpg)
Fundamental vs. Incidental in STL
c© 2009 Andrei Alexandrescu 8 / 52
• Algorithms defined for the narrowest interfacepossible
• Broad iterator categories as required by algorithms
• Choice of iterator primitives
• Syntax of iterator primitives
![Page 15: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/15.jpg)
Fundamental vs. Incidental in STL
c© 2009 Andrei Alexandrescu 8 / 52
• F: Algorithms defined for the narrowest interfacepossible
• Broad iterator categories as required by algorithms
• Choice of iterator primitives
• Syntax of iterator primitives
![Page 16: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/16.jpg)
Fundamental vs. Incidental in STL
c© 2009 Andrei Alexandrescu 8 / 52
• F: Algorithms defined for the narrowest interfacepossible
• F: Broad iterator categories as required by algorithms
• Choice of iterator primitives
• Syntax of iterator primitives
![Page 17: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/17.jpg)
Fundamental vs. Incidental in STL
c© 2009 Andrei Alexandrescu 8 / 52
• F: Algorithms defined for the narrowest interfacepossible
• F: Broad iterator categories as required by algorithms
• I: Choice of iterator primitives
• Syntax of iterator primitives
![Page 18: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/18.jpg)
Fundamental vs. Incidental in STL
c© 2009 Andrei Alexandrescu 8 / 52
• F: Algorithms defined for the narrowest interfacepossible
• F: Broad iterator categories as required by algorithms
• I: Choice of iterator primitives
• I: Syntax of iterator primitives
![Page 19: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/19.jpg)
STL: The Good
c© 2009 Andrei Alexandrescu 9 / 52
• Asked the right question
• General
• Efficient
• Reasonably extensible
• Integrated with built-in types
![Page 20: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/20.jpg)
STL: The Bad
c© 2009 Andrei Alexandrescu 10 / 52
• Poor lambda functions support
Not an STL problem
High opportunity cost
• Some containers cannot be supported
E.g. sentinel-terminated containers
E.g. containers with distributed storage
• Some iteration methods cannot be supported
![Page 21: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/21.jpg)
STL: The Ugly
c© 2009 Andrei Alexandrescu 11 / 52
• Attempts at for_each et al. didn’t help
• Integration with streams is tenuous
• One word: allocator
![Page 22: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/22.jpg)
STL: The Ugly
c© 2009 Andrei Alexandrescu 11 / 52
• Attempts at for_each et al. didn’t help
• Integration with streams is tenuous
• One word: allocator
• Iterators suck
◦ Verbose
◦ Unsafe
◦ Poor Interface
![Page 23: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/23.jpg)
What’s the Deal with Iterators?
c© 2009 Andrei Alexandrescu 12 / 52
![Page 24: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/24.jpg)
Iterators Rock
c© 2009 Andrei Alexandrescu 13 / 52
• They broker interaction between containers andalgorithms
• “Strength reduction:” m + n implementations instead ofm · n
• Extensible: there’s been a flurry of iterators ever sinceSTL saw the light of day
![Page 25: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/25.jpg)
Warning Sign #1
c© 2009 Andrei Alexandrescu 14 / 52
• C++ Users Journal around 2001 ran an ad campaign
“Submit an article to CUJ!”
“No need to be an English major! Just start youreditor!”
“We’re interested in security, networking, C++techniques, and more!”
![Page 26: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/26.jpg)
Warning Sign #1
c© 2009 Andrei Alexandrescu 14 / 52
• C++ Users Journal around 2001 ran an ad campaign
“Submit an article to CUJ!”
“No need to be an English major! Just start youreditor!”
“We’re interested in security, networking, C++techniques, and more!”
“Please note: Not interested in yet another iterator”
• How many of those published iterators survived?
![Page 27: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/27.jpg)
Warning Sign #2
c© 2009 Andrei Alexandrescu 15 / 52
File copy circa 1975:
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF)
putchar(c);
return errno != 0;
}
![Page 28: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/28.jpg)
Warning Sign #2
c© 2009 Andrei Alexandrescu 16 / 52
Fast forward 20 years, and. . .
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
int main() {
copy(istream_iterator<string>(cin),
istream_iterator<string>(),
ostream_iterator<string>(cout,"\n"));
}
![Page 29: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/29.jpg)
c© 2009 Andrei Alexandrescu 17 / 52
(forgot the try/catch around main)
![Page 30: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/30.jpg)
c© 2009 Andrei Alexandrescu 18 / 52
Something, somewhere, went terribly wrong.
![Page 31: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/31.jpg)
Warning Sign #3
c© 2009 Andrei Alexandrescu 19 / 52
• Iterators are brutally hard to define
• Bulky implementations and many gotchas
• Boost includes an entire library that helps definingiterators
• The essential primitives are like. . . three?
◦ At end◦ Access◦ Bump
![Page 32: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/32.jpg)
Warning Sign #4
c© 2009 Andrei Alexandrescu 20 / 52
• Iterators use pointer syntax & semantics
• Integration with pointers for the win/loss
• However, this limits methods of iteration
◦ Can’t walk a tree in depth, need ++ with aparameter
◦ Output iterators can only accept one type:ostream_iterator must be parameterized witheach specific type to output, although they all go tothe same place
![Page 33: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/33.jpg)
Final nail in the coffin
c© 2009 Andrei Alexandrescu 21 / 52
• All iterator primitives are fundamentally unsafe
• For most iterator types, given an iterator
◦ Can’t say whether it can be compared
◦ Can’t say whether it can be incremented
◦ Can’t say whether it can be dereferenced
• Safe iterators can and have been written
◦ At a high size+speed cost
◦ Mostly a good argument that the design hasn’tbeen cut quite right
![Page 34: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/34.jpg)
Ranges
c© 2009 Andrei Alexandrescu 22 / 52
![Page 35: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/35.jpg)
Enter Ranges
c© 2009 Andrei Alexandrescu 23 / 52
• To partly avoid these inconveniences, ranges havebeen defined
• A range is a pair of begin/end iterators packed together
• As such, a range has higher-level checkable invariants
• Boost and Adobe libraries defined ranges
![Page 36: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/36.jpg)
c© 2009 Andrei Alexandrescu 24 / 52
They made an interesting step in a good direction.
![Page 37: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/37.jpg)
c© 2009 Andrei Alexandrescu 25 / 52
Things must be taken much further.
![Page 38: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/38.jpg)
Look, Ma, no iterators!
c© 2009 Andrei Alexandrescu 26 / 52
• How about defining ranges instead of iterators as theprimitive structure for iteration?
• Ranges should define primitive operations that do notrely on iteration
• There would be no more iterators, only ranges
• What primitives should ranges support?
Remember, begin/end are not an option
If people squirrel away individual iterators, we’reback to square one
![Page 39: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/39.jpg)
Defining Ranges
c© 2009 Andrei Alexandrescu 27 / 52
• All of <algorithm> should be implementable withranges, and other algorithms as well
• Range primitives should be checkable at low cost
• Yet, ranges should not be less efficient than iterators
![Page 40: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/40.jpg)
Input/Forward Ranges
c© 2009 Andrei Alexandrescu 28 / 52
template<class T> struct InputRange {
bool empty() const;
void popFront();
T& front() const;
};
![Page 41: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/41.jpg)
Verifiable?
c© 2009 Andrei Alexandrescu 29 / 52
template<class T> struct ContigRange {
bool empty() const { return b >= e; }
void popFront() {
assert(!empty());
++b;
}
T& front() const {
assert(!empty());
return *b;
}
private:
T *b, *e;
};
![Page 42: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/42.jpg)
Find
c© 2009 Andrei Alexandrescu 30 / 52
// Original version per STL
template<class It, class T>
It find(It b, It e, T value) {
for (; b != e; ++b)
if (value == *b) break;
return b;
}
...
auto i = find(v.begin(), v.end(), value);
if (i != v.end()) ...
![Page 43: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/43.jpg)
Design Question
c© 2009 Andrei Alexandrescu 31 / 52
• What should find with ranges look like?
1. Return a range of one element (if found) or zeroelements (if not)?
2. Return the range before the found element?
3. Return the range after the found element?
![Page 44: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/44.jpg)
Design Question
c© 2009 Andrei Alexandrescu 31 / 52
• What should find with ranges look like?
1. Return a range of one element (if found) or zeroelements (if not)?
2. Return the range before the found element?
3. Return the range after the found element?
• Correct answer: return the range starting with the foundelement (if any), empty if not found
![Page 45: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/45.jpg)
Design Question
c© 2009 Andrei Alexandrescu 31 / 52
• What should find with ranges look like?
1. Return a range of one element (if found) or zeroelements (if not)?
2. Return the range before the found element?
3. Return the range after the found element?
• Correct answer: return the range starting with the foundelement (if any), empty if not found
Why?
![Page 46: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/46.jpg)
Find
c© 2009 Andrei Alexandrescu 32 / 52
// Using ranges
template<class R, class T>
R find(R r, T value) {
for (; !r.empty(); r.popFront())
if (value == r.front()) break;
return r;
}
...
auto r = find(v.all(), value);
if (!r.empty()) ...
![Page 47: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/47.jpg)
Elegant Specification
c© 2009 Andrei Alexandrescu 33 / 52
template<class R, class T>
R find(R r, T value);
“Reduces the range r from left until its front is
equal with value or r is exhausted.”
![Page 48: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/48.jpg)
Bidirectional Ranges
c© 2009 Andrei Alexandrescu 34 / 52
template<class T> struct BidirRange {
bool empty() const;
void popFront();
void popBack();
T& front() const;
T& back() const;
};
![Page 49: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/49.jpg)
Reverse Iteration
c© 2009 Andrei Alexandrescu 35 / 52
template<class R> struct Retro {
bool empty() const { return r.empty(); }
void popFront() { return r.popBack(); }
void popBack() { return r.popFront(); }
E<R>::Type& front() const { return r.back(); }
E<R>::Type& back() const { return r.front(); }
R r;
};
template<class R> Retro<R> retro(R r) {
return Retro<R>(r);
}
template<class R> R retro(Retro<R> r) {
return r.r; // klever
}
![Page 50: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/50.jpg)
How about find_end?
c© 2009 Andrei Alexandrescu 36 / 52
template<class R, class T>
R find_end(R r, T value) {
return retro(find(retro(r));
}
• No more need for rbegin, rend
• Containers define all which returns a range
• To iterate backwards: retro(cont.all())
![Page 51: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/51.jpg)
find_end with iterators sucks
c© 2009 Andrei Alexandrescu 37 / 52
// find_end using reverse_iterator
template<class It, class T>
It find_end(It b, It e, T value) {
It r = find(reverse_iterator<It>(e),
reverse_iterator<It>(b), value).base();
return r == b ? e : --r;
}
• Crushing advantage of ranges: much terser code
• Easy composition because only one object needs to becomposed, not two in sync
![Page 52: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/52.jpg)
More composition opportunities
c© 2009 Andrei Alexandrescu 38 / 52
• Chain: chain several ranges together
Elements are not copied!
Category of range is the weakest of all ranges
• Zip: span several ranges in lockstep
Needs Tuple
• Stride: span a range several steps at once
Iterators can’t implement it!
• Radial: span a range in increasing distance from itsmiddle (or any other point)
![Page 53: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/53.jpg)
How about three-iterators functions?
c© 2009 Andrei Alexandrescu 39 / 52
template<class It1, It2>
void copy(It1 begin, It1 end, It2 to);
template<class It>
void partial_sort(It begin, It mid, It end);
template<class It>
void rotate(It begin, It mid, It end);
template<class It, class Pr>
It partition(It begin, It end, Pr pred);
template<class It, class Pr>
It inplace_merge(It begin, It mid, It end);
![Page 54: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/54.jpg)
c© 2009 Andrei Alexandrescu 40 / 52
“Where there’s hardship, there’s opportunity.”
– I. Meade Etop
![Page 55: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/55.jpg)
3-legged algos ⇒ mixed-range algos
c© 2009 Andrei Alexandrescu 41 / 52
template<class R1, class R2>
R2 copy(R1 r1, R2 r2);
• Spec: Copy r1 to r2, returns untouched portion of r2
vector<float> v;
list<int> s;
deque<double> d;
copy(chain(v, s), d);
![Page 56: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/56.jpg)
3-legged algos ⇒ mixed-range algos
c© 2009 Andrei Alexandrescu 42 / 52
template<class R1, class R2>
void partial_sort(R1 r1, R2 r2);
• Spec: Partially sort the concatenation of r1 and r2
such that the smallest elements end up in r1
• You can take a vector and a deque and put the smallestelements of both in the array!
vector<double> v;
deque<double> d;
partial_sort(v, d);
![Page 57: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/57.jpg)
But wait, there’s more
c© 2009 Andrei Alexandrescu 43 / 52
vector<double> v1, v2;
deque<double> d;
partial_sort(v1, chain(v2, d));
sort(chain(v1, v2, d));
• Algorithms can now operate on any mixture of rangesseamlessly without any extra effort
• Try that with iterators!
![Page 58: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/58.jpg)
But wait, there’s even more
c© 2009 Andrei Alexandrescu 44 / 52
vector<double> vd;
vector<string> vs;
// sort the two in lockstep
sort(zip(vs, vd));
• Range combinators allow myriads of new uses
• Possible in theory with iterators, but the syntax wouldexplode (again)
![Page 59: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/59.jpg)
Output ranges
c© 2009 Andrei Alexandrescu 45 / 52
• Freedom from pointer syntax allows supporting differenttypes
struct OutRange {
typedef Typelist<int, double, string> Types;
void put(int);
void put(double);
void put(string);
}
![Page 60: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/60.jpg)
Back to copying stdin to stdout
c© 2009 Andrei Alexandrescu 46 / 52
#include <...>
int main() {
copy(istream_range<string>(cin),
ostream_range(cout, "\n"));
}
• Finally, a step forward: a one-liner that fits on one line1
• ostream_range does not need to specify string
1slide limitations notwithstanding
![Page 61: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/61.jpg)
Infinite ranges
c© 2009 Andrei Alexandrescu 47 / 52
• Notion of infinity becomes interesting with ranges
• Generators, random numbers, series, . . . are infiniteranges
• Infinity is a trait distinct from the five classic categories;any kind of range may be infinite
• Even a random-access range may be infinite!
• Statically knowing about infinity helps algorithms
![Page 62: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/62.jpg)
has_size
c© 2009 Andrei Alexandrescu 48 / 52
• Whether a range has an efficiently computed size isanother independent trait
• (Index entry: list.size, endless debate on)
• Even an input range can have a known size, e.g.take(100, rndgen) which takes 100 randomnumbers
◦ take(100, r) has length 100 if r is infinite◦ length min(100, r.size()) if r has known
length◦ unknown length if r is finite with unknown length
![Page 63: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/63.jpg)
A Twist
c© 2009 Andrei Alexandrescu 49 / 52
• Can <algorithm> be redone with ranges?
• D’s stdlib offers a superset of <algorithm> in modulesstd.algorithm and std.range (google for them)
• Ranges pervade D: algorithms, lazy evaluation, randomnumbers, higher-order functions, foreachstatement. . .
• Some opportunities not yet tapped—e.g. filters(input/output ranges)
• Check “The Case for D” in Doctor Dobb’s Journal,coming soon
![Page 64: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/64.jpg)
Conclusion
c© 2009 Andrei Alexandrescu 50 / 52
• Ranges are a superior abstraction
• Better checking abilities (not perfect still)
• Easy composition
• Range-based design offers much more than a port ofiterator-based functions to ranges
• Exciting development taking STL one step further
![Page 65: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/65.jpg)
Announcement
c© 2009 Andrei Alexandrescu 51 / 52
Please note: “The D ProgrammingLanguage” soon to appear on Safari’s
Rough Cuts.
![Page 66: Iterators Must Go - ACCU...Warning Sign #4 c 2009 Andrei Alexandrescu 20 / 52 • Iterators use pointer syntax & semantics • Integration with pointers for the win/loss • However,](https://reader030.fdocuments.us/reader030/viewer/2022040318/5e370bc6e0573b304363fbc6/html5/thumbnails/66.jpg)
Andrei Alexandrescu, Ph %@! D
c© 2009 Andrei Alexandrescu 52 / 52
Please note: Andrei will soon be offeringtraining and consulting services. Contact
him for details.