473,513 Members | 2,881 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is there such an iterator?

I've got a bunch of file_iterator<> (http://tinyurl.com/3uuxa)
begin/end pairs that point to various chunks in a file. It would be
super-cool, in my program, to be able to treat all of these ranges as
though they were one huge range. I'm envisioning something along the
lines of a library facility that provides an iterator type that
encapsulates a set of ranges and abstracts out code to handle
traversal through all of them as though all the little sets of ranges
were one big one.

Maybe this will help clarify:

int main(void)
{
vector<pair<file_iterator<>, file_iterator<> >
ranges(2);

ranges.at(0).first = file_iterator<>("somefile.txt");
ranges.at(0).second = ranges.at(0).first + 5;

ranges.at(1).first = ranges.at(0).second + 5;
ranges.at(1).second = ranges.at(1).first + 5;

// this is fictional
typedef single_range_emulating_iterator</*some stuff here*/>
sre_iterator;

sre_iterator begin(ranges);
sre_iterator end = begin.make_end(); // or something

// this results in a traversal through all the ranges.
for_each(begin, end, some_operation());
}

Is there such a thing? Is such a thing possible?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #1
4 1588
"Arturo Cuebas" <do**@want.spam> wrote in message
I've got a bunch of file_iterator<> (http://tinyurl.com/3uuxa)
begin/end pairs that point to various chunks in a file. It would be
super-cool, in my program, to be able to treat all of these ranges as
though they were one huge range. I'm envisioning something along the
lines of a library facility that provides an iterator type that
encapsulates a set of ranges and abstracts out code to handle
traversal through all of them as though all the little sets of ranges
were one big one.


There is no such segmented iterator in the standard library, though the
implementation of std::deque is a little along the lines you describe.
Wonder if boost has such a class. Anyway, it would be something like

template <class Iter>
class segmented_iterator {
public:
typedef typename std::iterator_traits<Iter>::value_type value_type;
typedef typename std::iterator_traits<Iter>::pointer pointer;
segmented_iterator(const std::vector<Iter>& begins, const
std::vector<Iter>& ends);
reference operator*() const { return *d_iter; }
pointer operator->() const;
const segmented_iterator operator++(int) {
segmented_iterator out = *this;
++*this;
return out;
}
segmented_iterator operator++() {
++d_iter;
if (d_iter == d_ends[d_current]) {
++d_current;
if (d_current < d_begins.size()) {
d_iter = d_begins[d_current];
}
return *this;
}
}
bool operator!=(const segmented_iterator& that) const {
return
this->d_current != that.d_current
|| this->d_iter != that.d_iter
;
}
private:
std::vector<Iter> d_begins;
std::vector<Iter> d_ends;
size_type d_current;
Iter d_iter;
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #2
Arturo Cuebas wrote:
I've got a bunch of file_iterator<> (http://tinyurl.com/3uuxa)
begin/end pairs that point to various chunks in a file. It would be
super-cool, in my program, to be able to treat all of these ranges as
though they were one huge range. I'm envisioning something along the
lines of a library facility that provides an iterator type that
encapsulates a set of ranges and abstracts out code to handle
traversal through all of them as though all the little sets of ranges
were one big one.


I don't know whether there is a ready made iterator for this (you
might want to check <http://www.boost.org/>) but it seems fairly
easy to create it: You just store your vector of pairs of iterators
(or a pointer to the corresponding vector) in one of the iterators.
The past-the-end iterator would store no data.

Effectively, you would create an iterator iterating over a sequence
of segments (quite similar to the iterator of 'std::deque'): It
would store information about the current segment and the position
of the segment in the vector of pairs. Advancing the iterator would
actually advance an iterator into the current segment switching to
the next segment if it hits the end of the current segment. If all
segments are processed, the iterator would compare equal to the
past the end iterator.

Here is an untested sketch of the code:

| template <typename Cont>
| class segment_pair_iterator
| {
| public:
| typedef typename Cont::value_type::first_type seg_iterator;
| segment_pair_iterator(): m_cont() { init(); }
| explicit
| segment_pair_iterator(Cont const& cont): m_cont(cont) { init(); }
|
| typename std::iterator_traits<seg_iterator>::reference
| operator*() const { return *m_seg_current; }
| segment_pair_iterator& operator++() {
| if (++m_seg_current == m_seg_end) {
| if (++m_cur_segment != m_cont.end()) {
| m_seg_current = m_cur_segment->first;
| m_seg_end = m_cur_segment->second;
| }
| }
| return *this;
| }
|
| bool operator== (segment_pair_iterator const& it) const {
| return (m_cur_segment == m_cont.end())
| == (it->m_cur_segment == it->m_cont.end());
| }
| // more members, mostly with derived logic...
| private:
| void init() {
| m_cur_segment = m_cont.begin();
| if (m_cur_segment != m_cont.end()) {
| m_seg_current = m_cur_segment->first;
| m_seg_end = m_cur_segment->second;
| }
| }
| Cont m_cont;
| typename Cont::const_iterator m_cur_segment;
| seg_iterator m_seg_current;
| seg_iterator m_seg_end;
| };
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #3
Such a class wouldn't be that difficult to write, here's something that
I cobbled together just now (standard warning applies; hasn't been
tested, yadda, yadda, yadda), should give you an idea where to start
----Begin code ---
#include <deque>
#include <utility>

template<typename Iterator>
class DisjointIterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type
value_type;
typedef typename std::iterator_traits<Iterator>::difference_type
difference_type;
typedef typename std::iterator_traits<Iterator>::pointer pointer;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef const reference const_reference;
typedef const pointer const_pointer;

private:
bool m_is_end;
std::deque<std::pair<Iterator,Iterator> > m_iters; //Pairs of begin
and end iterators
Iterator m_iter;
Iterator m_next_end;

void pop_next_iterator_range()
{
m_is_end = m_iters.empty();
if(!m_is_end)
{
m_iter = m_iters.front().first;
m_next_end = m_iters.front().second;
m_iters.pop_front();
}
}

public:
DisjointIterator() : m_is_end(true) {}
DisjointIterator(const DisjointIterator &other) :
m_is_end(other.m_is_end), m_iters(other.m_iters), m_iter(other.m_iter),
m_next_end(other.m_next_end) {}
template<typename IteratorListInputIterator> //Should be an
InputIterator into a sequence of std::pair<Iterator,Iterator>
DisjointIterator(IteratorListInputIterator iter,
IteratorListInputIterator end)
{
for(;iter != end; ++iter)
{
if(iter->first != iter->second)
{
m_iters.push_back(*iter);
}
}

pop_next_iterator_range();
}

DisjointIterator &operator=(const DisjointIterator &other)
{
m_is_end = other.m_is_end;
m_iters = other.m_iters;
m_iter = other.m_iter;
m_next_end = other.m_next_end;
return *this;
}

DisjointIterator &operator++()
{
if(!m_is_end)
{
++m_iter;
if(m_iter == m_next_end)
{
pop_next_iterator_range();
}
}
return *this;
}

DisjointIterator operator++(int)
{
DisjointIterator temp(*this);
++*this;
return temp;
}

bool operator==(const DisjointIterator &other) const
{
if(m_is_end)
{
return other.m_is_end;
}
else
{
return m_iter == other.m_iter;
}
}

bool operator!=(const DisjointIterator &other) const { return
!operator==(other); }
reference operator*() { return *m_iter; }
const_reference operator*() const { return *m_iter; }

pointer operator->() { return &(operator*()); }
const_pointer operator->() const { return &(operator*()); }
};
---- end code ----

And, for a sanity check, I just used it like so:

---- begin code ----
#include <vector>
using std::vector;

#include <utility>
using std::pair;
using std::make_pair;

#include <iterator>
using std::ostream_iterator;

#include <iostream>
using std::cout;

int main()
{
vector<int> vec;

for(int i = 0; i<100; ++i)
{
vec.push_back(i);
}

vector<pair<vector<int>::iterator, vector<int>::iterator> > iters;

iters.push_back(make_pair(vec.begin(), vec.begin()+3));
iters.push_back(make_pair(vec.begin()+20, vec.begin()+20));
iters.push_back(make_pair(vec.begin()+21, vec.begin()+30));
iters.push_back(make_pair(vec.begin()+90, vec.end()));
iters.push_back(make_pair(vec.begin()+20, vec.begin()+25));

DisjointIterator<vector<int>::iterator>
disjoint_begin(iters.begin(), iters.end());
DisjointIterator<vector<int>::iterator> disjoint_end;

std::copy(disjoint_begin, disjoint_end, ostream_iterator<int>(cout,
", "));

cout << "\n";

return 0;
}
---- end code ----

Which produced the following output:
0, 1, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 20, 21, 22, 23, 24,
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #4
On 01/11/2005 03:48 AM, Dietmar Kuehl wrote:
Arturo Cuebas wrote:
I've got a bunch of file_iterator<> (http://tinyurl.com/3uuxa)
begin/end pairs that point to various chunks in a file. It would be
super-cool, in my program, to be able to treat all of these ranges as
though they were one huge range. I'm envisioning something along the
[snip] I don't know whether there is a ready made iterator for this (you
might want to check <http://www.boost.org/>) but it seems fairly

There's also something in the boost files that does something
similar. The file is:

http://groups.yahoo.com/group/boost/...tor%20Adaptor/

You have to join the group to see the file, but that's not hard.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
5609
by: Adelein and Jeremy | last post by:
I am taking a second programming course in Java and am currently attempting to apply what I have learned using Python instead. One thing that is puzzling me is how to use an iterator. I am writing a module containing everything I'd need for canonical linked lists. One particularly useful feature would be to use a for loop over the whole...
38
3638
by: Grant Edwards | last post by:
In an interview at http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=273 Alan Kay said something I really liked, and I think it applies equally well to Python as well as the languages mentioned: I characterized one way of looking at languages in this way: a lot of them are either the agglutination of features or they're a...
3
2776
by: CoolPint | last post by:
If I were to design my own container and its iterators, I understand that I need to provide both "iterator" and "const_iterator" so that begin() and end() return appropriate ones depending on the "constantness" of the container object. I also note that is it done through overloading begin() and end() like below: iterator begin();...
0
1369
by: CoolPint | last post by:
I am trying to write a generic heapsort (of course as a self-exercise) with Iterator interface: something like blow.... But I got into trouble finding out the Iterator to the Child node. If indexing was used, I could do something like child = hole * 2 + 1; but since only thing the function accepts are random access Iterators, how do I...
26
1514
by: Michael Klatt | last post by:
I am trying to write an iterator for a std::set that allows the iterator target to be modified. Here is some relvant code: template <class Set> // Set is an instance of std::set<> class Iterator { public : typedef typename Set::value_type T; typedef typename Set::iterator SetIterator; Iterator(Set& container, const SetIterator& it);
0
1937
by: nick | last post by:
Hi, I need to manage a "layered" collection of objects, where each layer grows independently, e.g, o--+--+--+--+--+ 1st layer | o 2nd layer (empty) | o--+--+--+ 3rd layer |
16
2558
by: mailforpr | last post by:
How do I do that? The thing is, the only information I have about the iterator is the iterator itself. No container it is belonging to or anything. Like template<Iteratorvoid totally_isolated(Iterator& it) { //how do I find out if it points to the end node? }
27
5295
by: Steven D'Aprano | last post by:
I thought that an iterator was any object that follows the iterator protocol, that is, it has a next() method and an __iter__() method. But I'm having problems writing a class that acts as an iterator. I have: class Parrot(object): def __iter__(self): return self def __init__(self): self.next = self._next()
4
1991
by: mkborregaard | last post by:
Hi, I have the weirdest problem, and I can not see what is going wrong. I have made a 2d container class, and am implementing an iterator for that class. However, the ++ operator is behaving very strange. The implementation looks like this (there is a lot of code, but I have only included it all for consistency. The problem is quite small and...
0
7269
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7177
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7559
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
5701
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4756
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3248
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3237
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1611
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
811
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.