Revised RFC on range design for D2

Sergey Gromov snake.scaly at gmail.com
Tue Sep 16 09:13:04 PDT 2008


Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> Sergey Gromov wrote:
> > Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> >> Sergey Gromov wrote:
> >>> Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> >>>> Given that in D const is transitive, we can't operate with const the 
> >>>> same way C++ does. Consider something as trivial as a copy:
> >>>>
> >>>> Tgt copy(Src, Tgt)(Src src, Tgt tgt)
> >>>> {
> >>>>      for (; !src.done; src.next) tgt.put(src.tip);
> >>>> }
> >>>>
> >>>> Problem is, you won't be able to copy e.g. an int[][] to another because 
> >>>> the types aren't compatible.
> >>> If Src is an input range you must make a deep copy.  This holds true for 
> >>> your current design also.  So this algorithm is flawed and it's good if 
> >>> it won't compile.
> >> Great point. I need to sleep on this some more.
> > 
> > Then I'll continue to think aloud.
> [snip]
> 
> Thanks for the code samples, they're cool. I hit a problem related to 
> the return type of head. Consider writing a range that iterates two 
> other ranges in lockstep. A very useful generic range. I started coding 
> it like this:
> 
> struct Lockstep(R0, R1)
> {
>      private R0 _r0;
>      private R1 _r1;
>      this(R0 r0, R1 r1)
>      {
>         _r0 = r0;
>         _r1 = r1;
>      }
> 
>      bool empty()
>      {
>          return _r0.empty || _r1.empty;
>      }
> 
>      Tuple!(ElementType!(R0), ElementType!(R1)) head()
>      {
>          return tuple(_r0.head, _r1.head);
>      }
> 
>      void next()
>      {
>          _r0.next;
>          _r1.next;
>      }
> }

Thinking aloud is fun.  :P

What you basically want to achieve is that

	Lockstep l1, l2;
	l1.head = l2.head;

translates into

	l1._r0.head = l2._r0.head;
	l1._r1.head = l2._r1.head;

all by itself.  Umm...  The simplest for a programmer would be compiler-
supported multiple return values and multiple assignment:

	ref typeof(R0.head), ref typeof(R1.head) head()
	{
	  return _r0.head, _r1.head;
	}

then

	l1.head = l2.head

is actually

	l1._r0.head, l1._r1.head = l2._r0.head, l2._r1.head;

I'm not expecting this to be implemented though.  Other methods, 
including returning a Tulpe!(), all return a struct.  There's no use in 
returning references there, even if we could, as long as structs are 
bit-copied.  All the tricks with reference fields rely substantially on 
the compiler performing specific actions on a per-field basis.


More information about the Digitalmars-d-announce mailing list