Re: [boost] Determining interest in combining_iterator

2003-03-29 Thread Thomas Becker
[EMAIL PROTECTED] wrote:
 FWIW, I've extended my pair iterator to be a tuple
 iterator for
 input/forward/bidirectional/random-access iterator
 categories, which was
 relatively painless. I will boostify it, add output
 iterator support back in,
 and test it with VC7.1 as well as g++ 3.2.2, if you
 (or anyone else) are
 interested.

Well, this combining iterator thing is the first time
I'm ever submitting anything to boost, so I don't know
if I should give advice, but what I did was to click
on Submissions at www.boost.org and it said that
Step 1 was to post a description of the proposed
submission to the boost mailing list to determine
interest. So that's what I did, and I suppose that's
what you should do too.

In my case, the response was not overwhelming, but it
wasn't devastating either, and I got a positive from
David Abrahams. So what I'll do next is to check out
their new iterator adaptor stuff in the sandbox and
see how my stuff fits in there or can be made to fit
in. Since my combining iterator would have to be part
of the iterator adaptor library, it will then
ultimately be David's, Jeremy's and Thomas' decision
whether they want it in there or not. Thanks a bunch
for yall's feedback so far. It has certainly helped me
sort things out.

Finally, Anthony: As I look at the new iterator
adaptor in the sandbox, I will of course keep an eye
on whether their changes have any bearing on the
relationship between what you have and what I have.
Under the current boost iterator adaptor, I think it
is clear that yours and mine are at least as different
from each other as the transform iterator is different
from the projection iterator, and hence they are two
separate things. It may be a while until I get around
to working on all this again, so let me know if you
have any new insights in this regard.

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV
[EMAIL PROTECTED]


__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Determining interest in combining_iterator

2003-03-28 Thread Thomas Becker
[EMAIL PROTECTED] wrote:

 Thomas Becker [EMAIL PROTECTED] writes:
  Unless I'm missing something, I believe that my
  original rough intuition was ok. Given my
 combining
  iterator, it seems very easy to write your tuple
  iterator by providing a simple generic
  reference-tuple-making functional.

[...]

 The returned tuple of references is not copyable
 though --- the copies will
 still refer to the originals. I went through all
 this with my pair iterator;
 try using std::sort on your pair of vectors,
 especially with vectors of a
 non-POD UDT with no swap specialization, just to
 avoid any optimizations in
 your standard library. A plain tuple-of-references
 will screw up the vectors,
 you need something more complex.
 
 Also, you can't use a tuple-of-references with input
 iterators, since they
 return values not references when dereferenced, so
 you need to know the
 iterator category and use a tuple of values in this
 case.
 
 Finally, output iterators are even more bizarre, as
 writing to the result of
 dereferencing your combined output iterator needs to
 write to the result of
 dereferencing each of the individual output
 iterators, and there is no telling
 what type you get when you dereference an output
 iterator.
  

I see now that with your tuple iterator, you are
aiming much higher than I previously thought. Just
like boost's transform iterators, my combining
iterators are always and necessarily input iterators.
(That's not really going to change under the new
proposed iterator categories, although they'll help
me.) I can cheat a little by returning a value that
happens to hold a bunch of references, such as a
boost::tuple of references. Nothing prevents me from
doing that. But you want a parallel-iterator that one
can, for example, pass to std::sort and have it order
the underlying sequences lexicographically. That's a
tall order. My combining iterator does not cover that.
Neither do I think that my combining iterator is
affected much by the ultimate solution to your
problem. My combining iterator is a multi-dimensional
boost::transforming_iterator. Yours would end up being
a multi-dimensional boost::projection_iterator. That's
a different colored horse.

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV
[EMAIL PROTECTED]

__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Determining interest in combining_iterator

2003-03-27 Thread Thomas Becker

--- Anthony Williams
[EMAIL PROTECTED] wrote:

 Basically, I think we have two contradictory
 scenarios. IIUC, the situations
 you have encountered are where you have a set of
 values in different
 containers that needed to be combined into a single
 value, in which case it
 makes sense to pass the values as distinct function
 arguments to a functor
 that does the combining.

That's true, that was the scenario that the combining
iterator grew out of, and that has certainly tilted my
perception of the problem in that direction. But when
I conceived of my combining iterator, I *did* think
about the other scenario that you mention:

 
 OTOH, the situations I am thinking of require that
 the tuple of containers is
 really treated as a container of tuples, complete
 with the ability to update
 the source containers by writing to the tuple
 obtained by the dereferencing,
 but maintaining the value semantics when copied.
 This is really hard to do in
 any other way than by having *it return a magic
 tuple, IMHO, though if you
 can find a way of doing it as a functor that just
 works without the user
 having to know too much, I'll concede the point.

Because of my tilted perception, I sort of dismissed
that scenario by saying to myself, ah, shucks, just
write a functional that returns a suitable reference,
and you're good. You are now forcing me to think about
this more carefully, for which I am grateful to you.
Unless I'm missing something, I believe that my
original rough intuition was ok. Given my combining
iterator, it seems very easy to write your tuple
iterator by providing a simple generic
reference-tuple-making functional. As always in
these situations, it's a little messy to provide one
functional that will work for all n (n=number of
member iterators), so for simplicity, here's the case
n=2:

templatetypename Type1_, typename Type2_
class FunMakeReferenceTuple_2
{
public:
  typedef boost::tupleType1_, Type2_ result_type;
  boost::tupleType1_, Type2_ operator()(
Type1_ refFirst,
Type2_ refSecond
) const
  {
return boost::tupleType1_, Type2_(
  refFirst, 
  refSecond
  );
  }
};

I've tested this in several examples, e.g., I created
two vectors of ints, filled them with values to equal
length, then created a combining_iterator from the two
begin positions and the functional 

FunMakeReferenceTuple_2int, int

Once I have this combining iterator, I can read and
write both vector elements to my hearts delight. E.g.,

std::swap(it-get0(), it-get1());

will swap the values at the current position, or,

*it = boost::make_tuple(42, 43);

will assign 42 and 43 to the respective vector
elements.

If you want to, you can easily wrap all this up and
provide a tuple_iterator which internally uses my
combining iterator in conjunction with the
reference-tuple-making functional. I now strongly
believe that that's the way to go. The combining
iterator handles for you everything that has to do
with the parallel-iteration. Via the funcional, you
decide how to process the dereferenced iterators. The
tuple_iterator is the special case (or rather, the
large subclass of cases) where that processing
consists of making a tuple of references. There's
certainly more to think about, like, what about const
tuple iterators, but I believe that the questions and
answers are the same whether you write the tuple
iterator from scratch or use my combining iterator. In
fact, doing it with the combining iterator seems
somehow intellectually cleaner to me, because all
the parallel iteration stuff is hidden and out of the
way, so you can focus on the tuple issues.

BTW, in my software, I do have cases where I need to
parallel iterate and write to the current positions,
but in those cases, I always deal with sequences of
possibly different length (think portfolio of assets
with different dates of inception). Now
parallel-iteration is really ugly business. There's
always a bigger can of worms...

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV
[EMAIL PROTECTED]


__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Determining interest in combining_iterator

2003-03-26 Thread Thomas Becker
 Anthony Williams wrote:
 The particular example I cited in the
 article is where a colleague
 had a pair of vectors which were the x and y values
 respectively for a
 graph. They were supplied as two vectors, and the
 graph drawing code required
 them as two vectors, yet the analysis code in the
 middle required a sequence
 of (x,y) pairs

I have to admit this very example has convinced me
that my original approach is right. Suppose we were to
write, as you suggest, an iterator adaptor that holds
a tuple of iterators and, upon dereferencing, returns
a tuple made from the dereferenced iterators. What
would we have done for the person in your example?
Nothing. He needs a *pair*, not a tuple. The big
picture is: we want an iterator that parallel-iterates
through several sequences, and upon dereferencing,
applies some user-defined (via a functional)
prossesing to the dereferenced iterators. If the
desired result is a pair, supply a functional that
makes a pair from its arguments. In my applications, I
want a number that is calculated from the dereferenced
iterators, so I supply something like std::divides. If
the desired result is a tuple made from the
dereferenced iterators, no problem, supply a
functional that makes a tuple from its arguments. If
we used your approach, we would give this one special
type of processing, where a tuple is made from the
dereferenced iterators, a very special and prominent
place in the design. Why? It's just one of infinitely
many things that someone might want to do.
(Ironically, it's the one for which we have not seen a
real-life need.) My general approach covers it with no
fuss and no overhead. One simple iterator adaptor that
does it all. We get everything that we would get in
your approach, and it's simpler and more
user-friendly. Unless I'm missing something...

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV
[EMAIL PROTECTED]


__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Determining interest in combining_iterator

2003-03-26 Thread Thomas Becker
 On 26 Mar 2003, Anthony Williams wrote:
  It strikes me that if you dereference n iterators,
 you have n values, and the
 most natural way to store them is a tuple.

--- Douglas Paul Gregor [EMAIL PROTECTED] wrote:
 I would agree if tuples and argument passing were
 more closely linked,
 i.e., if passing a tuple to a function meant that
 the tuple would be
 automagically unpacked into separate arguments.

From a user's point of view, this seems a very strong
argument to me. For instance, in my software, I use
combining iterators with functionals such as
std::divides. If I were forced to accept my arguments
as a tuple, I couldn't use any of these functionals
without the extra unpacking step. Besides, introducing
the tuple in the middle between dereferencing the
iterators introduces the possibility of inadvertent
extra value copies. Another big headache for the user.
And why all that? I really don't see any advantage to
this intermediate step of packaging the derefernced
iterators into a tuple, only to unpack it in 99.999%
of the cases. What for?

Once again: The big picture is that we want an
iterator that parallel-iterates over several sequences
and upon dereferencing, applies some processing to the
dereferenced iterator. This processing is specified by
the user via a fuctional. One of the many, many things
that such a functional can do is package the arguments
into a tuple, if that is what's needed. (Although we
still haven't seen a single real-life request for
that). Why  on earth would I, in the general case,
introduce a packaging/unpackaging step in the middle
between dereferencing the iterators and passing them
to the functional? Am I missing something?

BTW, Anthony: In one of my CUJ columns, I made a big
fool of myself by gratuitously packaging function
arguments into a tuple, and I seem to remember that
you were one of the people who pointed this out to me.
Looks like we switched sides in this argument... ;-)

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV

__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Determining interest in combining_iterator

2003-03-25 Thread Thomas Becker
Thanks for your comments on the combining iterator.

 David Abrahams wrote:
 It's a wonderful idea, Thomas!

 You might look at the Boost sandbox; Jeremy Siek,
 Thomas Witt and I
 are trying to finalize the work in the 
 boost/iterator and
 libs/iterator directories to replace the current 
 iterator adaptors

Thanks for your kind words. I'll play with the sanbox
stuff. Is the main
purpose there to incorporate better iterator
categories? Anyway, I won't take any further action
until all that has settled down.

 Douglas Paul Gregor wrote:
 Sounds great. Since the functionality is a direct 
 generalization of
 transform_iterator, I'd prefer to use the name 
 transform_iterator and
 either (a) switch entirely to your 
 combining_iterator implementation or
 (b) give transform_iterator_generator the brains to 
 switch between your
 implementation and the existing implementation based

 on the number of
 iterators being adapted.

Uh uh, I was kinda hoping nobody would bring that up,
because I agree and at the same time strongly
disagree. Of course you're right, the transforming
iterator is a special case of the combining iterator,
and under any kind of theoretical point of view, it
should be treated as such. There is no way I can argue
with you on that. And yet, I am very strongly in favor
of keeping the two entirely separate. Here's why: From
a library user's point of view, the fact that the
transforming iterator is a special case of the
combining iterator is quite accidental. If someone is
looking for the functionality of the transforming
iterator, she should find just that, without being
forced to view the thing she's looking for as a
special case of something completely different. One
could in fact express this viewpoint in a somewhat
theoretical manner by saying that the transforming
iterator is not so much a *special* case of the
combining iterator than a *degenerate* case. Combining
iterators is not where one would naturally look when
in need of a transforming iterator.

 Anthony Williams wrote:
 IMHO, it seems more logical to split the concept, so

 the grouping of 
 the iterators is separated from the transformation

By separating the grouping and the transforming, do
you mean to write an iterator that holds a tuple of
iterators and then, upon dereferencing, returns the
tuple of dereferenced values, and then use that in
conjunction with boost's transforming iterator? That
would make a lot of sense. However, I would need a
little convincing that it really adds useful
functionality that people are looking for.

 Paul A. Bristow wrote:
 I can see this VERY useful to some, but probably not

 widely useful. 

In view of the emphasis on very, I'll count that as
a yes vote.

Thomas Becker
Zephyr Associates, Inc.
Zephyr Cove, NV

__
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost