range iterator

Discussion in 'C++' started by toton, Aug 24, 2006.

  1. toton

    toton Guest

    Hi,
    I want ro iterate over a few container class within a range
    specified, instead of begin & end.
    How to construct a range class, which takes start & end, and iteration
    is available within that range only. Itaration may be const,
    bidiractional, forward or backward.

    Say I have a vector or other container class,
    like vector<int> vec;
    and want to return a range class like range(vec.begin()+5,
    vec.end() - 10);
    range will have a begin & end to denote start & end of the range,
    but beyond the range is not allowed to be iteraded.
    Actually, I have a large no of objects stored in a container, a range
    of them belongs to a particular instance, who is allowed to modify it.
    Those ranges are sometimes overlapping also.
    some only needs a const iterator while other needs modification (may
    not be deletion, which itself modifies the range!). I want each
    instance to return it's associated range for iteration.
    Thanks for any suggestion.
     
    toton, Aug 24, 2006
    #1
    1. Advertising

  2. toton

    Kai-Uwe Bux Guest

    toton wrote:

    > Hi,
    > I want ro iterate over a few container class within a range
    > specified, instead of begin & end.
    > How to construct a range class, which takes start & end, and iteration
    > is available within that range only. Itaration may be const,
    > bidiractional, forward or backward.
    >
    > Say I have a vector or other container class,
    > like vector<int> vec;
    > and want to return a range class like range(vec.begin()+5,
    > vec.end() - 10);
    > range will have a begin & end to denote start & end of the range,
    > but beyond the range is not allowed to be iteraded.
    > Actually, I have a large no of objects stored in a container, a range
    > of them belongs to a particular instance, who is allowed to modify it.
    > Those ranges are sometimes overlapping also.
    > some only needs a const iterator while other needs modification (may
    > not be deletion, which itself modifies the range!). I want each
    > instance to return it's associated range for iteration.


    You could start with a simple adaptor like this:

    template < typename Iterator >
    class range {

    Iterator start;
    Iterator past_end;

    public:

    typedef typename iterator_traits< Iterator >::size_type size_type;

    range ( Iterator const & from, Iterator const & to )
    : start ( from )
    , past_end ( to )
    {}

    size_type size ( void ) const {
    typename iterator_traits< Iterator >::difference_type
    dist = std::distance( this->start, this->past_end );
    assert( dist >= 0 );
    return ( dist );
    }

    Iterator begin ( void ) const {
    return( start );
    }

    Iterator end ( void ) const {
    return( this->past_end );
    }

    bool empty ( void ) const {
    return( this->start == this->past_end );
    }

    }; // class range<>

    The use of the assert is debatable. Ideally, one would check the validity of
    the range upon construction and throw something if [from,to) is not sound.
    However, that might be inefficient (for non-random access iterators) or
    impossible (if from and to point to different containers).


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Aug 24, 2006
    #2
    1. Advertising

  3. toton

    toton Guest

    Kai-Uwe Bux wrote:
    > toton wrote:
    >
    > > Hi,
    > > I want ro iterate over a few container class within a range
    > > specified, instead of begin & end.
    > > How to construct a range class, which takes start & end, and iteration
    > > is available within that range only. Itaration may be const,
    > > bidiractional, forward or backward.
    > >
    > > Say I have a vector or other container class,
    > > like vector<int> vec;
    > > and want to return a range class like range(vec.begin()+5,
    > > vec.end() - 10);
    > > range will have a begin & end to denote start & end of the range,
    > > but beyond the range is not allowed to be iteraded.
    > > Actually, I have a large no of objects stored in a container, a range
    > > of them belongs to a particular instance, who is allowed to modify it.
    > > Those ranges are sometimes overlapping also.
    > > some only needs a const iterator while other needs modification (may
    > > not be deletion, which itself modifies the range!). I want each
    > > instance to return it's associated range for iteration.

    >
    > You could start with a simple adaptor like this:
    >
    > template < typename Iterator >
    > class range {
    >
    > Iterator start;
    > Iterator past_end;
    >
    > public:
    >
    > typedef typename iterator_traits< Iterator >::size_type size_type;
    >
    > range ( Iterator const & from, Iterator const & to )
    > : start ( from )
    > , past_end ( to )
    > {}
    >
    > size_type size ( void ) const {
    > typename iterator_traits< Iterator >::difference_type
    > dist = std::distance( this->start, this->past_end );
    > assert( dist >= 0 );
    > return ( dist );
    > }
    >
    > Iterator begin ( void ) const {
    > return( start );
    > }
    >
    > Iterator end ( void ) const {
    > return( this->past_end );
    > }
    >
    > bool empty ( void ) const {
    > return( this->start == this->past_end );
    > }
    >
    > }; // class range<>
    >
    > The use of the assert is debatable. Ideally, one would check the validity of
    > the range upon construction and throw something if [from,to) is not sound.
    > However, that might be inefficient (for non-random access iterators) or
    > impossible (if from and to point to different containers).
    >

    Yes, this is a good example. but someone can iterate past range, is it
    not? like someone can go end+10 or start-5 also. Is there a way to
    prevent out of range in iterator? I am not sure how to do it as the
    iterator itself does not throw out_of_range.
    Anything can be done to prevent out of range?
    secondly, if I have a class instance which knows the range from the
    constructor, is it better to store the range in object, and return the
    range as reference? or store only the start & end location, and return
    a constructed range object when range is needed?

    > Best
    >
    > Kai-Uwe Bux
     
    toton, Aug 24, 2006
    #3
  4. toton

    toton Guest

    Kai-Uwe Bux wrote:
    > toton wrote:
    >
    > > Hi,
    > > I want ro iterate over a few container class within a range
    > > specified, instead of begin & end.
    > > How to construct a range class, which takes start & end, and iteration
    > > is available within that range only. Itaration may be const,
    > > bidiractional, forward or backward.
    > >
    > > Say I have a vector or other container class,
    > > like vector<int> vec;
    > > and want to return a range class like range(vec.begin()+5,
    > > vec.end() - 10);
    > > range will have a begin & end to denote start & end of the range,
    > > but beyond the range is not allowed to be iteraded.
    > > Actually, I have a large no of objects stored in a container, a range
    > > of them belongs to a particular instance, who is allowed to modify it.
    > > Those ranges are sometimes overlapping also.
    > > some only needs a const iterator while other needs modification (may
    > > not be deletion, which itself modifies the range!). I want each
    > > instance to return it's associated range for iteration.

    >
    > You could start with a simple adaptor like this:
    >
    > template < typename Iterator >
    > class range {
    >
    > Iterator start;
    > Iterator past_end;
    >
    > public:
    >
    > typedef typename iterator_traits< Iterator >::size_type size_type;
    >
    > range ( Iterator const & from, Iterator const & to )
    > : start ( from )
    > , past_end ( to )
    > {}
    >
    > size_type size ( void ) const {
    > typename iterator_traits< Iterator >::difference_type
    > dist = std::distance( this->start, this->past_end );
    > assert( dist >= 0 );
    > return ( dist );
    > }
    >
    > Iterator begin ( void ) const {
    > return( start );
    > }
    >
    > Iterator end ( void ) const {
    > return( this->past_end );
    > }
    >
    > bool empty ( void ) const {
    > return( this->start == this->past_end );
    > }
    >
    > }; // class range<>
    >
    > The use of the assert is debatable. Ideally, one would check the validity of
    > the range upon construction and throw something if [from,to) is not sound.
    > However, that might be inefficient (for non-random access iterators) or
    > impossible (if from and to point to different containers).
    >

    Yes, this is a good example. but someone can iterate past range, is it
    not? like someone can go end+10 or start-5 also. Is there a way to
    prevent out of range in iterator? I am not sure how to do it as the
    iterator itself does not throw out_of_range.
    Anything can be done to prevent out of range?
    secondly, if I have a class instance which knows the range from the
    constructor, is it better to store the range in object, and return the
    range as reference? or store only the start & end location, and return
    a constructed range object when range is needed?
    thanks for the help.
    > Best
    >
    > Kai-Uwe Bux
     
    toton, Aug 24, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    46
    Views:
    987
    Antoon Pardon
    Jul 25, 2006
  2. Lambda
    Replies:
    2
    Views:
    414
    James Kanze
    Jul 16, 2008
  3. Tomoyuki Kosimizu

    Range does not take an Range object.

    Tomoyuki Kosimizu, Nov 25, 2003, in forum: Ruby
    Replies:
    3
    Views:
    159
    Tomoyuki Kosimizu
    Nov 27, 2003
  4. David Bird
    Replies:
    1
    Views:
    223
    Tiago Macedo
    Jun 23, 2008
  5. Joey Zhou
    Replies:
    5
    Views:
    240
    Joey Zhou
    Apr 15, 2011
Loading...

Share This Page