Boost logo

Boost :

From: Matthew Wilson (stlsoft_at_[hidden])
Date: 2003-11-19 04:01:39


> > You can also manually set the beginning and end of a range:
> > // ignore first and last 5 elements
> > r.begin( v.begin() + 5);
> > r.end( v.end() - 5);
> > while( r)
> > std::cout << *r++ << std::endl;
>
> why not just make a new one providing the smaller range as arguments to
the
> constructor?

He he. This is one of the areas about which John and I are still in debate.
I'm in favour of the simplest-is-best, but John favours the resettable
ranges. John's got more "hand", though, since he's done most of the work.

> > The basic range classes are:
> > template< class container> class crange;
> > template< class iterator> class irange;
> >
> > Examples of usage:
> > crange< const container> r(...); // const range
> > crange< container> nr( ...); // non-const range
> > irange< iterator_type> ir(...); // from iterator
> >
> > A range can be created from a container/const container/2 iterators.
> > crange< container> r( cont); // const or non-const container
> > crange< container> r( beg, end); // two iterators
> >
> > A range preserves the underlying iterator properties.
>
> what is the benefit of crange? AFAICT, irange is all we need.

We need to distinguish between the range concept, and a particular
implementation. As far as I'm concerned a range is simply something that
fits the expression:

  for(; r; ++r)
  {
    *r; // Do something with the element at the current enumeration point.
  }

Everything else is implementation.

Having said that, John's done a pretty fine first implementation, based
strongly around interroperability with Boost, so any fat that's got in there
is more than forgiveable. I plan, eventually, to do an STLSoft
implementation, which will probably be more minimalistic, since I'm lazier.
:) I'm hoping that we can spark sufficient debate in this forum that we can
refine the concept down to its bare minimum, from which it may be applied in
all kinds of places. (As John mentioned in the post, there are plans to use
Ranges in other languages, where suitable. I'm also interested to see if/how
it might work with LambaLib, about which I'm only just starting to learn.)

> > 2. range algorithms
> > All STL algorithms are implemented for ranges as well.
> > (note: currently we have not implemented mismatch and
partial_sort_copy).
> >
> > For the purpose of ALL range algorithms, a container IS a range.
> > Therefore, the following is possible:
> >
> > typedef std::list<int> array;
> > array l;
> > l.resize( 50);
> > rng::generate( l, next() ); // next() is a functor
> > rng::reverse( l);
> > // prints the given list to console
> > rng::copy( l, std::ostream_iterator<int>(std::cout," ") );
>
> there is no major difference between this and the stuff in the sandbox.
One
> thing
> might be that if the container traits (soon to be rename collection
traits)
> is used, we can use ordinary arrays too with the algorithms.

Yes. I've got container-based algorithms, and that's partly what sparked
this effort. John and I were chatting about a shared dissatisfaction with
the verbosity of iterators when one wants to step outside the standard
functors, and I mentioned that I'd got these container-based algorithms, but
wasn't particularly thrilled with them. Then John shared his ideas for
ranges, as we are now getting to know them, and a star was born. ;)

For my money, the important thing with ranges is, as I've said above, the
simplified loop structure. John's focus is on adaptability, and I think he's
got some serious mileage in those aspects of the concept. The
container/iterator/range algorithms are less noteworthy, and should not be
taken to be "the big new thing", since they can be done without a need for
ranges.

Another important feature that, for all we STL-fans, is easy to overlook is
that ranges do not need to be based on any "real" nature (in respect of
existing in a container, or in the range of an iterator pair). In fact the
first range I wrote was integral_range, which looks roughly like:

template <typename T>
class integral_range
{
public:
    typedef T value_type;

public:
    integral_range(value_type first, value_type last, value_type increment =
+1);

private:
    struct boolean { int i; };
public:
    operator int boolean::*() const;

    value_type operator *() const;
    class_type &operator ++();

    bool operator ==(class_type const &rhs) const
    bool operator !=(class_type const &rhs) const

// Members
private:
    value_type m_position;
    value_type m_last;
    value_type m_increment;
};

Anyway, I'm sure you get the idea. :)

> > We are also still debating the precise definition of the Range Concept,
> > and anticipate that your opinions will help cement the matter. We're
> hoping
> > that the range concept can be applied to other languages, and are
> envisaging
> > looking at C#(.NET) and D at a future time.
>
> As mentioned, there has already been some discussions regarding this.

Do you mean application to other languages as well, or just to the notion in
general.

> In the
> files section, one can find
> Jeremy's collection cencept which seems like the right thing (without
> swap())

Sounds interesting. I'd like to look into it. Any chance of the right url,
for a total Boost neophyte?

Cheers

-- 
Matthew Wilson
STLSoft moderator (http://www.stlsoft.org)
Contributing editor, C/C++ Users Journal
(www.synesis.com.au/articles.html#columns)
"You can tell a Yorkshireman, but you can't tell him much!" -- Uncle Michael
----------------------------------------------------------------------------
---

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk