Boost logo

Boost :

From: Dean Michael Berris (mikhailberis_at_[hidden])
Date: 2008-06-24 10:17:10


On Tue, Jun 24, 2008 at 9:26 PM, Mathias Gaunard
<mathias.gaunard_at_[hidden]> wrote:
> Dean Michael Berris wrote:
>
>> Almost does it, but not necessarily. Constructing an instance of the
>> transform iterator would require the instantiation of the
>> counting_iterator as well.
>>
>> template <class ResultType, class InputType>
>> struct generator {
>> typedef transform_iterator<
>> function<ResultType(InputType)>, counting_iterator<InputType>
>> > iterator;
>> typedef iterator const const_iterator;
>>
>> iterator begin() {
>> return make_transform_iterator(
>> counting_iterator<InputType>(), _function
>> );
>> };
>> [...]
>
> By using ranges instead of iterators, you can get that container-like
> behaviour (grouping of begin and end).
>
> However counting_range doesn't seem to be implemented yet.
>

Interesting... Would the range provide the overload to operator[] to
create an associative pseudo-container that behaves like a container?
Perhaps something like (using C++0x auto):

  auto f_sequence = make_lazy_function_range( begin, end, function() );
  f_sequence[1]; // like *(++begin);

?

I think the generator works at a different level than ranges and/or
iterators. The ideas are complimentary IMO:

  double function_1(int i) {
    return (numeric_cast<double>(i)*2.0)
      + 1.0;
  }; // 2x + 1
  double function_2(int i) {
    return numeric_cast<double>(i)
      * numeric_cast<double>(i)
      + 1.0;
  }; // 2^x + 1

  ...

  generator<double, int> f_1(function_1);
  generator<double, int> f_2(function_2);

  for_each(
    make_zip_iterator(make_tuple(f_1.begin(), f_2.begin())),
    make_zip_iterator(make_tuple(f_1.begin() + 5, f_2.begin() + 5))),
    deal_with_data_points()
  );

  iterator_range<
    generator<double, int>::const_iterator
> first_10_f_1s(f_1.begin(), f_1.begin() + 5);

This way, dereferencing the iterator would cause the function to be
invoked and a value to be produced (much like a transform iterator).
Also, much like for example some mathematical sequences and/or tables
where values can be looked up from, the abstraction provided by a
generated sequence container instead of just iterators and ranges can
be very useful.

If it helps thinking about it like a lazy associative container where
values are only computed as necessary, then I think that would be one
way you can think about the generator example/proposal.

  // with phoenix for example
  generator<int, int> doubles(arg1 * 2);
  doubles[100]; // 200

HTH

-- 
Dean Michael C. Berris
Software Engineer, Friendster, Inc.

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