Implementing swap for user-defined swaps

2017-10-07 Thread Balagopal Komarath via Digitalmars-d-learn

Hello,

  I was implement my own range type that forwards all accesses to 
another range. I tried to write a `swap` function so that sort 
etc. could be called on my range. However, I cannot get 
`hasSwappableElements!ARange` to evaluate to true. But, when I 
copy pasted the definition of `hasSwappableElements` into my 
module and evaluated it, it was true. I assume this is something 
to do with how name lookup works in D. Here's simplified code 
that reproduces the same problem.


https://dpaste.dzfl.pl/48a420cce261

Thanks,
Balagopal.


Re: Using mixin templates for operator overloading.

2017-08-20 Thread Balagopal Komarath via Digitalmars-d-learn

On Sunday, 20 August 2017 at 12:46:59 UTC, Nicholas Wilson wrote:
Did you try changing the `: "+"` constraints to `if` 
constraints?


Yes. Yields the same result as this.



Re: Using mixin templates for operator overloading.

2017-08-20 Thread Balagopal Komarath via Digitalmars-d-learn
On Saturday, 19 August 2017 at 10:16:18 UTC, Balagopal Komarath 
wrote:
Let us say I want to automatically define subtraction given 
that addition and negation are defined. I tried the following 
using mixin templates...


I assume there is no way to do this?



Using mixin templates for operator overloading.

2017-08-19 Thread Balagopal Komarath via Digitalmars-d-learn
Let us say I want to automatically define subtraction given that 
addition and negation are defined. I tried the following using 
mixin templates. If I simply mixin the template using "mixin 
sub;", then it gives the error


tmpmixin.d(29): Error: incompatible types for ((a) - (b)): 'A!0' 
and 'A!0'


I found out that mixin using an identifier for template mixins 
and then using an alias declaration as in the code given below 
can be used to bring in overloads. But, this produces the error.


tmpmixin.d(23): Error: alias tmpmixin.A!0.A.opBinary conflicts 
with template tmpmixin.A!0.A.opBinary(string op : "+")(in A 
other) at tmpmixin.d(14)
tmpmixin.d(29): Error: template instance tmpmixin.A!0 error 
instantiating


As you can see, there is no conflict logically. One defines 
addition and the mixin defines subtraction.


What is the right way to do this?

mixin template sub()
{
alias T = typeof(this);

T opBinary(string op : "-")(in T other) const
{
return this + (-other);
}
}

struct A(int x)
{
int a;
A opBinary(string op : "+")(in A other) const
{
return A(this.a + other.a);
}
A opUnary(string op : "-")() const
{
return A(-a);
}
mixin sub ops;
alias opBinary = ops.opBinary;
}

void main()
{
import std.stdio : writeln;
auto a = A!0(5), b = A!0(6);
writeln(a-b);
}



Re: Implicit conversion from const to mutable

2017-08-17 Thread Balagopal Komarath via Digitalmars-d-learn
On Thursday, 17 August 2017 at 20:22:09 UTC, Steven Schveighoffer 
wrote:


This should "work". I don't think your static assert will pass, 
but the main function below should run.


Thanks. But, isn't my static assert testing for exactly this?



Implicit conversion from const to mutable

2017-08-17 Thread Balagopal Komarath via Digitalmars-d-learn
Is it possible to make structs containing slices support implicit 
conversion from const to mutable? I tried adding a postblit that 
dupes the member 'a'. That didn't work.


struct A
{
int[] a;
}

void main()
{
static assert (is(const(A) : A)); // fails
}


Re: How to partially apply member functions?

2017-07-01 Thread Balagopal Komarath via Digitalmars-d-learn

On Friday, 30 June 2017 at 08:43:32 UTC, ct wrote:

It compiled when I wrote:

auto on_next_previous = 
entry_.addOnNextMatch(!(on_next_previous, true));
entry_.addOnPreviousMatch(!(on_next_previous, false));

But not when I wrote:

entry_.addOnNextMatch(partial!(, 
true));


Or

entry_.addOnNextMatch(partial!(, 
true));


Error: value of 'this' is not known at compile time


In the first snippet, you are passing the local variable 
on_next_previous by alias to the template and not the function 
 AFAIK, when the partial function is 
invoked at a later point of time, it will use the value of the 
variable at the invocation time and not the value of the variable 
at the time of the invocation of partial! template. The following 
snippet should clarify this.


import std.stdio;
import std.traits;

template partial(alias f, alias arg1, T = Parameters!f[1])
{
auto g(T arg2)
{
return f(arg1, arg2);
}
enum partial = 
}

int foo(int x, int y)
{
writeln("foo");
return x + y;
}

struct bar
{
int id;
int baz(int x, int y)
{
writeln("bar.baz", id);
return x + y;
}
}

void main()
{
auto foo2 = partial!(foo, 2);
writeln(foo2(3));

auto b = bar(0);
auto bbaz = 
auto bar2 = partial!(bbaz, 2);
writeln(bar2(3)); // bar.baz0 5
auto c = bar(1);
bbaz = 
writeln(bar2(3)); // bar.baz1 5
}

One might think that in the above code, bar2 is set to the 
partial function b.baz(2, *). But, it is clear that that is not 
the case. There is no partially applied function here. When bar2 
is invoked, it invokes the function in the variable bbaz with the 
argument given at the time of the template invocation and the 
argument given during function invocation.


The snippet


partial!(, true)


doesn't work because templates cannot accept runtime values as 
arguments since they work at compile time. The only things that 
are available at compile time are symbols and literal values.


Hope this makes sense.


Re: Overloading funtion templates.

2017-06-30 Thread Balagopal Komarath via Digitalmars-d-learn

On Friday, 30 June 2017 at 04:51:23 UTC, vit wrote:

import std.traits : isCallable;

auto foo(alias F, T)(T x)
if(isCallable!F)//this line is optional
{
return F(x);
}



Thanks. That works.




Overloading funtion templates.

2017-06-28 Thread Balagopal Komarath via Digitalmars-d-learn
Shouldn't the compiler be able to resolve foo!g(3) to the first 
template foo?


import std.stdio;
import std.algorithm;
import std.range;

auto foo(F, T)(T x)
{
return x.foo(F);
}

auto foo(F, T)(T x, F f)
{
return f(x);
}

int g(int x) { return x; }

void main()
{
foo(3, ); // 2nd foo
foo!g(3);   // error
}

I get the error message.

onlineapp.d(20): Error: template onlineapp.foo cannot deduce 
function from argument types !(g)(int), candidates are:

onlineapp.d(5): onlineapp.foo(F, T)(T x)
onlineapp.d(10):onlineapp.foo(F, T)(T x, F f)



Re: Implementing interfaces using alias this

2017-06-15 Thread Balagopal Komarath via Digitalmars-d-learn

On Thursday, 15 June 2017 at 07:12:56 UTC, Biotronic wrote:

Here however, is a solution that works for simple examples.



This is awesome. Very generic. Thanks.


Re: Implementing interfaces using alias this

2017-06-14 Thread Balagopal Komarath via Digitalmars-d-learn

On Wednesday, 14 June 2017 at 21:04:55 UTC, basile b. wrote:

The way to do that in D is with mixins:


That is an interesting solution.

However, my original goal was to figure out whether one can make 
struct types behave polymorphically (Which is not mentioned in my 
original question).  I know that this is not supported by design. 
I want to keep the original struct types but also allow functions 
to accept those struct types and do runtime dispatch. The 
following code should give a better idea by what I mean by this.


https://dpaste.dzfl.pl/051f6a4da059

The user need only define Duck1, Duck2 ... with appropriate 
functions and mixin toDuck. Then a function that accepts a Duck 
can accept DuckLike (for dynamic dispatch) or templatize on the 
type of Duck.


Re: Implementing interfaces using alias this

2017-06-14 Thread Balagopal Komarath via Digitalmars-d-learn

On Wednesday, 14 June 2017 at 12:35:05 UTC, Mike B Johnson wrote:

void main()
{
Test!Duck d;
d.quack();
}

which, unfortunately causes a segmentation fault ;)


I think that is because you are not initializing d using new 
Test!Duck();


Re: Implementing interfaces using alias this

2017-06-14 Thread Balagopal Komarath via Digitalmars-d-learn

On Wednesday, 14 June 2017 at 11:40:02 UTC, ketmar wrote:
interfaces *require* a full-featured class, with VMT, and some 
hidden pointers to support hidden interface machinery.


I don't think that is the problem here. The type Test!Duck is a 
class and that type is the one implementing the interface.




Re: Implementing interfaces using alias this

2017-06-14 Thread Balagopal Komarath via Digitalmars-d-learn

On Wednesday, 14 June 2017 at 09:41:49 UTC, ketmar wrote:

Balagopal Komarath wrote:

Why doesn't this work? The Test!Duck type has a void quack() 
method but the compiler says it is not implemented.


'cause `alias this` is *not* a tool that can be used to emulate 
inheritance. no, `quack` is NOT impemented. `alias this` won't 
automagically paste the code.


Thanks for the reply. Is there any reason for disallowing this? 
AFAIK, the alias this guarantees that the interface provided by 
Test!T is a superset of the interface provided by T. And, when T 
= Duck, T provides everything required by IDuck. Couldn't the 
compiler check while instantiating that Test!Duck provides all 
methods required by IDuck?


Implementing interfaces using alias this

2017-06-14 Thread Balagopal Komarath via Digitalmars-d-learn
Why doesn't this work? The Test!Duck type has a void quack() 
method but the compiler says it is not implemented.


import std.stdio;

interface IDuck
{
void quack();
}

class Test(T) : IDuck
{
T data;
alias data this;
}

struct Duck
{
void quack()
{
writeln("Quack");
}
}


void main()
{
Test!Duck d;
}


Re: How to check whether a struct is templated?

2017-06-13 Thread Balagopal Komarath via Digitalmars-d-learn

Are you looking for something like this?

import std.typecons;
import std.traits;

alias yes = Nullable!int;

struct no {}

template isNullable(T : Nullable!X, X)
{
enum isNullable = true;
}

template isNullable(T)
{
enum isNullable = false;
}

void main()
{
static assert(isNullable!yes);
static assert(!isNullable!no);
}




Overloading for lvalue and rvalue.

2017-06-12 Thread Balagopal Komarath via Digitalmars-d-learn
Is there a way to avoid the following combinatorial explosion of 
overloaded functions when overloading for lvalue and rvalue 
arguments? The following may be a bad example because int is 
cheap to copy. So assume a large datatype instead of int.


import std.stdio;

void foo(in ref int a, in ref int b)
{
writeln("r, r");
}

void foo(in ref int a, in int b)
{
writeln("r, i");
}

void foo(in int a, in ref int b)
{
writeln("i, r");
}

void foo(in int a, in int b)
{
writeln("i, i");
}

void main()
{
int a, b;
foo(a, b);
foo(a, 0);
foo(0, a);
foo(0, 0);
}