It would be nice to write a DSL to generate some of the C++ boilerplate (say, containers, iterators, etc) required as a baseline before starting to solve the actual problem. A DSL could codify rules like the ones described in this article and generate at least a rough first pass to be hand-tuned later.
Writing a custom iterator in modern C++
31–40 of 79 posts
Re: Writing a custom iterator in modern C++
#32Somewhat related but C++20 ranges do not replace iterators and instead build a higher level of abstraction upon iterators. Ranges are implemented in terms of iterator pairs.
Re: Writing a custom iterator in modern C++
#33There's six different kinds of iterator?! Off hand, is it just me or... - Isn't an iterator that outputs data to its recipient container not an iterator, but rather some type of filling API? - Isn't a random access iterator not an iterator but rather a slice view? - Isn't a contiguous iterator a leaky abstraction in that an iterator is just an interface that shouldn't expose how the data backing it is stored? This it…
It's funny how two of the most common bandwagon posts you can see on HN and other programming venues is: * C++ is a terrible bloated language that no one should use. * The power of modern computers is wasted on lazy software engineers writing software with too many layers of abstraction.
Re: Writing a custom iterator in modern C++
#34Earlier quoted context omitted.
Iterators are inconsistent, but this plays to the strengths of C++'s duck-typed generics. The same code can either copy or insert, depending on whether you use std::begin or std::back_inserter; this isn't principled but it's powerful. The "six types of iterators" overstates it. You don't need to sweat those details unless you are writing boost or something. Just add what you need. I miss C++ iterators in other langua…
Backing up a utf8 stream is nontrivial though.
C++ is structured around iterators that point into; this enables e.g. writing into the guts of a std::map but not the guts of a std::string if you care about Unicode, since the write might change the string's byte length.
Re: Writing a custom iterator in modern C++
#35There's six different kinds of iterator?! Off hand, is it just me or... - Isn't an iterator that outputs data to its recipient container not an iterator, but rather some type of filling API? - Isn't a random access iterator not an iterator but rather a slice view? - Isn't a contiguous iterator a leaky abstraction in that an iterator is just an interface that shouldn't expose how the data backing it is stored? This it…
It's funny how two of the most common bandwagon posts you can see on HN and other programming venues is: * C++ is a terrible bloated language that no one should use. * The power of modern computers is wasted on lazy software engineers writing software with too many layers of abstraction.
Re: Writing a custom iterator in modern C++
#36Somewhat related but C++20 ranges do not replace iterators and instead build a higher level of abstraction upon iterators. Ranges are implemented in terms of iterator pairs.
Yeah. That actually sucks; often iterators doesn't fit the iteration model of some sequences, but ranges would fit right in if they didn't require separability into two iterators.
Re: Writing a custom iterator in modern C++
#37Earlier quoted context omitted.
Random access iterators mean you can efficiently advance or retreat an iterator by an arbitrary amount. So a vector (via pointer arithmetic) but not a linked list.
Right but why should this matter at the type level? All you need to implement is next() and annotate it with documentation of the performance characteristics.
Why describe at the type level the difference between a backwards pointer chase and a pointer decrement? The hope is: if you know at compile time that your iterator is efficient in this way, you can pick a more specialized algorithm, say, quicksort instead of mergesort. C++ really does enable this at the type level through template specialization. In practice the STL collections haven't lived up to this, and I think the iterator tags are mostly deadweight.
Re: Writing a custom iterator in modern C++
#38Somewhat related but C++20 ranges do not replace iterators and instead build a higher level of abstraction upon iterators. Ranges are implemented in terms of iterator pairs.
Yeah. That actually sucks; often iterators doesn't fit the iteration model of some sequences, but ranges would fit right in if they didn't require separability into two iterators.
Re: Writing a custom iterator in modern C++
#39The classic iterator categories (input, output, ...) discussed in this article have been deprecated in C++20, and replaced with new concepts. I would expect a post from 2020 claiming to be about iterators "in modern C++" to be specifically about that change, but actually it's just about the legacy categories, so this is a pretty worthless article.
An article using C++20 will just lead to frustration, as there are still rough edges using concepts, with a standard that was just published last week.
Re: Writing a custom iterator in modern C++
#40Earlier quoted context omitted.
Yeah. That actually sucks; often iterators doesn't fit the iteration model of some sequences, but ranges would fit right in if they didn't require separability into two iterators.
Can you give an example of such a sequence?
class DirectoryChildren
{
void *dir;
void *buffer;
size_t buffer_size;
size_t buffer_offset;
...
public:
bool next(FileInfo *info);
};
Bear in mind the buffer only represents a chunk of intermediate results fetched from the OS; when we reach its end, we have to request more data from the OS.If you had to make an iterator for this, what would you do? You'd basically need to either (a) create iterators that at least duplicate the entire state of DirectoryChildren on the stack, or (b) make iterators allocate on the heap. Both of these suck, because (1) iterators are passed around and copied all over the place on the assumption that these are fundamentally cheap operations, which is an assumption that easily breaks (like here), and (2) the iterators fundamentally do not have any meaning or utility as separate entities from the range itself.