473,651 Members | 2,630 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<fil e_iterator<>, file_iterator<> >
ranges(2);

ranges.at(0).fi rst = file_iterator<> ("somefile.txt" );
ranges.at(0).se cond = ranges.at(0).fi rst + 5;

ranges.at(1).fi rst = ranges.at(0).se cond + 5;
ranges.at(1).se cond = ranges.at(1).fi rst + 5;

// this is fictional
typedef single_range_em ulating_iterato r</*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++.m oderated. First time posters: Do this! ]
Jul 22 '05 #1
4 1605
"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_itera tor {
public:
typedef typename std::iterator_t raits<Iter>::va lue_type value_type;
typedef typename std::iterator_t raits<Iter>::po inter pointer;
segmented_itera tor(const std::vector<Ite r>& begins, const
std::vector<Ite r>& ends);
reference operator*() const { return *d_iter; }
pointer operator->() const;
const segmented_itera tor operator++(int) {
segmented_itera tor out = *this;
++*this;
return out;
}
segmented_itera tor 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!=(cons t segmented_itera tor& that) const {
return
this->d_current != that.d_current
|| this->d_iter != that.d_iter
;
}
private:
std::vector<Ite r> d_begins;
std::vector<Ite r> d_ends;
size_type d_current;
Iter d_iter;
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. 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_it erator
| {
| public:
| typedef typename Cont::value_typ e::first_type seg_iterator;
| segment_pair_it erator(): m_cont() { init(); }
| explicit
| segment_pair_it erator(Cont const& cont): m_cont(cont) { init(); }
|
| typename std::iterator_t raits<seg_itera tor>::reference
| operator*() const { return *m_seg_current; }
| segment_pair_it erator& operator++() {
| if (++m_seg_curren t == m_seg_end) {
| if (++m_cur_segmen t != m_cont.end()) {
| m_seg_current = m_cur_segment->first;
| m_seg_end = m_cur_segment->second;
| }
| }
| return *this;
| }
|
| bool operator== (segment_pair_i terator const& it) const {
| return (m_cur_segment == m_cont.end())
| == (it->m_cur_segmen t == 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_ite rator m_cur_segment;
| seg_iterator m_seg_current;
| seg_iterator m_seg_end;
| };
--
<mailto:di***** ******@yahoo.co m> <http://www.dietmar-kuehl.de/>
<http://www.contendix.c om> - Software Development & Consulting
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. 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<typena me Iterator>
class DisjointIterato r
{
public:
typedef std::input_iter ator_tag iterator_catego ry;
typedef typename std::iterator_t raits<Iterator> ::value_type
value_type;
typedef typename std::iterator_t raits<Iterator> ::difference_ty pe
difference_type ;
typedef typename std::iterator_t raits<Iterator> ::pointer pointer;
typedef typename std::iterator_t raits<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_iterat or_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_fro nt();
}
}

public:
DisjointIterato r() : m_is_end(true) {}
DisjointIterato r(const DisjointIterato r &other) :
m_is_end(other. m_is_end), m_iters(other.m _iters), m_iter(other.m_ iter),
m_next_end(othe r.m_next_end) {}
template<typena me IteratorListInp utIterator> //Should be an
InputIterator into a sequence of std::pair<Itera tor,Iterator>
DisjointIterato r(IteratorListI nputIterator iter,
IteratorListInp utIterator end)
{
for(;iter != end; ++iter)
{
if(iter->first != iter->second)
{
m_iters.push_ba ck(*iter);
}
}

pop_next_iterat or_range();
}

DisjointIterato r &operator=(cons t DisjointIterato r &other)
{
m_is_end = other.m_is_end;
m_iters = other.m_iters;
m_iter = other.m_iter;
m_next_end = other.m_next_en d;
return *this;
}

DisjointIterato r &operator++( )
{
if(!m_is_end)
{
++m_iter;
if(m_iter == m_next_end)
{
pop_next_iterat or_range();
}
}
return *this;
}

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

bool operator==(cons t DisjointIterato r &other) const
{
if(m_is_end)
{
return other.m_is_end;
}
else
{
return m_iter == other.m_iter;
}
}

bool operator!=(cons t DisjointIterato r &other) const { return
!operator==(oth er); }
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_it erator;

#include <iostream>
using std::cout;

int main()
{
vector<int> vec;

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

vector<pair<vec tor<int>::itera tor, vector<int>::it erator> > 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) );

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

std::copy(disjo int_begin, disjoint_end, ostream_iterato r<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++.m oderated. 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++.m oderated. 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
5619
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 structure. For this I have learned the benefits of iterators. I have read a few book entries on...
38
3660
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 crystallization of style. Languages such as APL, Lisp, and Smalltalk are what you might call style...
3
2783
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(); const_iterator begin() const; So it seems to me that I need to have two separate iterator classes
0
1379
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 calculate the Iterator to the child node? template <typename Iterator, typename Functor> void...
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
1943
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
2576
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
5307
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
2001
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 local): template<typename T> class Row<T> : public std::vector<T> {}; template<typename...
0
8349
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 usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8275
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8795
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8576
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6157
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5609
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4143
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 the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2696
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
2
1585
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.