www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Concepts like c++20 with specialized overload resolution.

reply vushu <danvu.hustle gmail.com> writes:
```
template <typename T>
concept HasMagma = requires(T l) { l.magma(); };

struct LavaMan {
   void magma() { std::cout << " LavaMan is throwing LAVA" << 
std::endl; }
};

struct FakeVulcano {
   void try_making_lava() { std::cout << " Making fake lava" << 
std::endl; }
};

void make_lava(HasMagma auto& lava) {
     lava.magma();
}

void make_lava(auto& lava_thing){
     lava_thing.try_making_lava();
}

int main() {
   LavaMan v;
   FakeVulcano l;
   make_lava(l);
   make_lava(v);
   return 0;
}
```

results in:
```
  Making fake lava
  LavaMan is throwing LAVA
```

Is there something equivalent in dlang, doesn't seem like d 
support specialized overload?
May 27 2023
next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Saturday, 27 May 2023 at 13:23:38 UTC, vushu wrote:
 [...]
 Is there something equivalent in dlang, doesn't seem like d 
 support specialized overload?
D solution is called [template constraints](https://dlang.org/spec/template.html#template_constraints).
May 27 2023
parent reply vushu <danvu.hustle gmail.com> writes:
On Saturday, 27 May 2023 at 13:42:29 UTC, Basile B. wrote:
 On Saturday, 27 May 2023 at 13:23:38 UTC, vushu wrote:
 [...]
 Is there something equivalent in dlang, doesn't seem like d 
 support specialized overload?
D solution is called [template constraints](https://dlang.org/spec/template.html#template_constraints).
Yes I know there is template constraint, but not with specialized overloading right? so you need to use static if for checking if it hasmagma.
May 27 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/27/23 9:50 AM, vushu wrote:
 On Saturday, 27 May 2023 at 13:42:29 UTC, Basile B. wrote:
 On Saturday, 27 May 2023 at 13:23:38 UTC, vushu wrote:
 [...]
 Is there something equivalent in dlang, doesn't seem like d support 
 specialized overload?
D solution is called [template constraints](https://dlang.org/spec/template.html#template_constraints).
Yes I know there is template constraint, but not with specialized overloading right? so you need to use static if for checking if it hasmagma.
What is missing is an "else" thing. So you have to repeat the constraint (as a negation) unfortunately. e.g.: ```d struct LavaMan { void magma() { writeln(" LavaMan is throwing LAVA"); } } struct FakeVulcano { void try_making_lava() { writeln(" Making fake lava"); } }; void make_lava(T)(ref T lava) if (hasMagma!T) { lava.magma(); } void make_lava(T)(ref T lava_thing) if (!hasMagma!T){ lava_thing.try_making_lava(); } ``` -Steve
May 27 2023
parent reply vushu <danvu.hustle gmail.com> writes:
On Saturday, 27 May 2023 at 16:38:43 UTC, Steven Schveighoffer 
wrote:
 On 5/27/23 9:50 AM, vushu wrote:
 On Saturday, 27 May 2023 at 13:42:29 UTC, Basile B. wrote:
 [...]
Yes I know there is template constraint, but not with specialized overloading right? so you need to use static if for checking if it hasmagma.
What is missing is an "else" thing. So you have to repeat the constraint (as a negation) unfortunately. e.g.: ```d struct LavaMan { void magma() { writeln(" LavaMan is throwing LAVA"); } } struct FakeVulcano { void try_making_lava() { writeln(" Making fake lava"); } }; void make_lava(T)(ref T lava) if (hasMagma!T) { lava.magma(); } void make_lava(T)(ref T lava_thing) if (!hasMagma!T){ lava_thing.try_making_lava(); } ``` -Steve
I see thanks for the example :), I think this probably the closest equivalent i dlang.
May 27 2023
next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Saturday, 27 May 2023 at 17:49:27 UTC, vushu wrote:
 On Saturday, 27 May 2023 at 16:38:43 UTC, Steven Schveighoffer 
 wrote:
 On 5/27/23 9:50 AM, vushu wrote:
 On Saturday, 27 May 2023 at 13:42:29 UTC, Basile B. wrote:
 [...]
Yes I know there is template constraint, but not with specialized overloading right? so you need to use static if for checking if it hasmagma.
What is missing is an "else" thing. So you have to repeat the constraint (as a negation) unfortunately. e.g.: ```d struct LavaMan { void magma() { writeln(" LavaMan is throwing LAVA"); } } struct FakeVulcano { void try_making_lava() { writeln(" Making fake lava"); } }; void make_lava(T)(ref T lava) if (hasMagma!T) { lava.magma(); } void make_lava(T)(ref T lava_thing) if (!hasMagma!T){ lava_thing.try_making_lava(); } ``` -Steve
I see thanks for the example :), I think this probably the closest equivalent i dlang.
I feel like overload in that case make things harder to read My example has less context switch, and hte logic is correctly understandable at first sight Only one make_lava function
May 27 2023
parent reply vushu <danvu.hustle gmail.com> writes:
On Saturday, 27 May 2023 at 18:41:47 UTC, ryuukk_ wrote:
 On Saturday, 27 May 2023 at 17:49:27 UTC, vushu wrote:
 On Saturday, 27 May 2023 at 16:38:43 UTC, Steven Schveighoffer 
 wrote:
 On 5/27/23 9:50 AM, vushu wrote:
 On Saturday, 27 May 2023 at 13:42:29 UTC, Basile B. wrote:
 [...]
Yes I know there is template constraint, but not with specialized overloading right? so you need to use static if for checking if it hasmagma.
What is missing is an "else" thing. So you have to repeat the constraint (as a negation) unfortunately. e.g.: ```d struct LavaMan { void magma() { writeln(" LavaMan is throwing LAVA"); } } struct FakeVulcano { void try_making_lava() { writeln(" Making fake lava"); } }; void make_lava(T)(ref T lava) if (hasMagma!T) { lava.magma(); } void make_lava(T)(ref T lava_thing) if (!hasMagma!T){ lava_thing.try_making_lava(); } ``` -Steve
I see thanks for the example :), I think this probably the closest equivalent i dlang.
I feel like overload in that case make things harder to read My example has less context switch, and hte logic is correctly understandable at first sight Only one make_lava function
It depends this example is quite small and a `static if` is sufficient, if you have a lot of cases it would make sense to split thing up into overloaded functions. imagine you are writing a library for handling vector or matrices that has a common `add` function. I just want to know the equivalent thing in dlang vs c++.
May 27 2023
parent Dom DiSc <dominikus scherkl.de> writes:
On Saturday, 27 May 2023 at 19:16:18 UTC, vushu wrote:
 It depends. This example is quite small and a `static if` is 
 sufficient, if you have a lot of cases it would make sense to 
 split thing up into overloaded functions.
Even with a lot of cases you can simply call in each static if a (private) subfunction. I would always prefer this over overloads because it gets you a much cleaner API (I consider the constraint to be part of the function signature, which therefore can get very long and produces a lot of overloads that each only differ in the constraints). Also it becomes more and more obfuscated for which cases there is an overload and for which not. A good (?!?) example of how bad this can get is the "to" template.
May 28 2023
prev sibling parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Sat, May 27, 2023 at 05:49:27PM +0000, vushu via Digitalmars-d-learn wrote:
 On Saturday, 27 May 2023 at 16:38:43 UTC, Steven Schveighoffer wrote:
[...]
 void make_lava(T)(ref T lava) if (hasMagma!T) {
     lava.magma();
 }
 
 void make_lava(T)(ref T lava_thing) if (!hasMagma!T){
     lava_thing.try_making_lava();
 }
[...]
 I see thanks for the example :), I think this probably the closest
 equivalent i dlang.
You can also use static if inside the function, which will give you an if-then-else structure: void make_lava(T)(ref T lava) { static if (hasMagma!T) { lava.magma(); } else { lava_thing.try_making_lava(); } } T -- Written on the window of a clothing store: No shirt, no shoes, no service.
May 27 2023
prev sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Saturday, 27 May 2023 at 13:23:38 UTC, vushu wrote:

you can use: ``static if (__traits(hasMember, T, "magma"))``


```D
import std;

struct LavaMan {
   void magma() { writeln(" LavaMan is throwing LAVA"); }
}

struct FakeVulcano {
   void try_making_lava() { writeln( " Making fake lava"); }
}


// all the magic
void make_lava(T)(ref T lava_thing){
     static if (__traits(hasMember, T, "magma"))
         lava_thing.magma();
     else
     	lava_thing.try_making_lava();
}

int main() {
   LavaMan v;
   FakeVulcano l;
   make_lava(l);
   make_lava(v);
   return 0;
}
```

```
  Making fake lava
  LavaMan is throwing LAVA
```
May 27 2023