The Phobos Put

Salih Dincer salihdb at hotmail.com
Wed Mar 29 20:29:57 UTC 2023


On Wednesday, 29 March 2023 at 19:49:47 UTC, Ali Çehreli wrote:
> On 3/29/23 12:21, ag0aep6g wrote:
>
> > As far as I understand, you're saying that we cannot overload
> on `ref`.
> > But we can. Salih's code demonstrates just that.
> >
> > void f(ref int x) {}
> > void f(int x) {}
> > void main() { int x; f(x); f(42); } /* no errors */
>
> I thought Salih was proposing two more overloads to the 
> existing put(). When I copy the existing put(), which takes 
> 'ref R', not R[], then the code does not compile:

Wait a minute, isn't `copy` actually a `put` as well? Forget 
about `ref` for a moment, please. Actually, logically, the 
parameters have been swapped between the two functions. Well, if 
we only had `copy` and we used `put` like `copy`, what is the 
need for `put`? Examples are below: :)

```d
//version = simple;/*
version = standart;//*/

version(simple) {
   auto put(R)(R[] range, R[] source)
     => copyImpl(source, range);

   auto copy(R)(R[] source, R[] range)
     => copyImpl(source, range);

   auto copyImpl(R)(R[] source, R[] range)
   {
     assert(source.length <= range.length);
     foreach(element; source)
     {
       range[0] = element;  // range.front()
       range = range[1..$]; // range.popFront()
     }
     return range;
   }

   void swap (ref int x, ref int y)
   {
     x = x ^ y;
     y = y ^ x;
     x = x ^ y;
   }
}

version(standart)
   import std.algorithm.mutation,
          std.range : put;

void main()
{
   // copy() example:
   enum len = 10;
   auto buf = new int[len]; // buffer
   auto dig = [7, 1, 2, 3]; // digits

   auto diff = len - dig.length;
   auto rem = copy(dig, buf);

   assert(buf[0..$ - diff] == [7, 1, 2, 3]);

   swap(buf[0], rem[0]);
   assert(rem == [7, 0, 0, 0, 0, 0]);

   // put() example 1:
   put(rem, [4, 5, 6, 7, 8, 9]);
   assert(buf == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

   // put() example 2:
   enum data = [1, 0, 0, 4];
   auto arr = data;
   auto slice = arr[1..$-1];

   version(standart)
     put(slice, [2]);
   version(simple)
     slice = put(slice, [2]);
   assert(arr == [1, 2, 0, 4]);

   version(standart)
     put(slice, [3]);
   version(simple)
     slice = put(slice, [3]);
   assert(arr == [1, 2, 3, 4]);

   version(standart) {
     auto slc = arr[1..$-1];
     put(slc, [0, 0]);
   }
   version(simple)
     arr[1..$-1].put([0, 0]);
   assert(arr == data);
}
```
All you have to do is remove the // mark in the first line. The 
code compiles for me, what about you?

SDB at 79


More information about the Digitalmars-d-learn mailing list