|
Boost : |
From: John Torjo (john.lists_at_[hidden])
Date: 2003-11-19 22:00:15
>
> well, if they are not random access, you can't do
>
> r.set_begin( v.begin() + 5 );
Of course, but you can do:
r.begin( r.advanced(5) ); // internally uses std::advance to advance the begin()
Or,
// converts v to a range, and advances begin()
r.begin( c_range(v).advanced(5) );
But you do have a very good point.
We should have a helper function advanced() which takes an iterator, a
ptrdiff_t, advances the iterator and returns it.
This is because the way std::advance is done, makes it pretty useless (it
returns void)
>
> if they are not bidirectional, you must do something like
>
> r.set_end( std::advanece( r.begin(), size( r ) - 5 ) );
nope. std::advance returns void (takes the iterator by reference).
>>Now, take a look at generated_range, which adapts a functor into a range.
>>This is pretty cool, and I see lots of places where that can be used.
>
>
> example:
> rng::copy( generated(step(), gen_n(10)),
> std::ostream_iterator<int>(std::cout," "));
>
> how does this relate to the generator_iterator already part of boost? Or the
About the generator_iterator, sorry I did not know about it.
I think it is misplaced - being put in the boost/ root, I never thought of
looking for it. Had I known it existed, I would have used it.
However, I only looked at the iterators existing in 'boost/iterator' directory.
One more thing - I think it's wrong to take the generator by reference and store
it by pointer as boost::generator_iterator does - what if the generator is a
function object.
template <class Generator>
inline generator_iterator<Generator>
make_generator_iterator(Generator & gen)
{
typedef generator_iterator<Generator> result_t;
return result_t(&gen);
}
Another thing is that this generator will never stop ;)
How do you create an end() iterator for this? ;)
Did you see how this is handled in generator_range?
> new iterators described in
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html ?
I'm reading it right now, anyway, there's a lot to read.
The point is the generated_range uses an *standard-conforming* input iterator.
>
> It's not that I don't believe you, I just don't have too much time figuring
> out how something can be used
> and why is it better than something we already got. If you wrote a design
> document
What do you mean? All of the range adaptors are based on existing iterator
adaptors (except for generated_range - I did not know about its existance)
> that explained why it was better than all known things on earth, it would be
> much easier for me to see.
>
> In the above code, I have a lot of unanswered questions, eg.
>
> why can't I say 10 instead of gen_n( 10 ) ? What's the performance of this
> compared to other implementations.
> I'm not sure, but I think functional C++ has a lot of similar stuff.
> What if I don't want the range [0,9] but [1,10] ?
Sorry there is no docs. right now.
The idea is that was just an example.
gen_n is the stopper. As said, sorry there is no docs. yet.
The idea behind a generated_range is this:
- you have a functor that you use to generate elements
- you need to create a range out of this. Therefore, you need to somehow
know when to stop (how many elements to generate).
So, you can create your own stopper, or use some existing ones.
A stopper is a predicate, which takes a value, and returns true if it's a
valid value (therefore, in the generated range), or false (not in the generated
range). First time the stopper returns false, the range ends. It's that simple ;)
Example:
// generates first 20 fibonacci numbers
generated(fibonacci(), gen_n(20));
// generates fibonacci numbers up to 200
// (note: you can't know from the beginning how many there are;
// thus, you use a stopper)
generated(fibonacci(), gen_upto(200));
> How is it better than this stuff I once wrote:
> http://www.cs.auc.dk/~nesotto/init/#Synopsis
> I'm thinking about the enum stuff or n_genereted_by.
I took a look, and the idea is brilliant! I love it!!!
But your library addresses a different problem - and it adresses it excellent!
What I want to do, is generate a range, and use it in STL algorithms, not
necessary to initialize something. For instance:
// multiplies each fibonacci number with its index:
// 1 * 0
// 2 * 1
// 3 * 2
// 5 * 3, etc.
std::cout << "\nFibonnacci numbers, multiplied by their index" << std::endl;
rng::transform(
generated( step(), gen_n(20)),
generated( fibonacci(), gen_n(20)),
std::ostream_iterator<int>(std::cout," "),
std::multiplies<int>() );
So, the generated_range is for a totally different purpose.
For initialization, your library is excellent!
>
> That is why I really need to see some docs. It will save both of us a lot of
> time.
>
You're totally right ;)
We need to do some docs in the following weeks.
Best,
John
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk