Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-09 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 9 February 2023 at 20:05:06 UTC, Ali Çehreli wrote:

Besides, D has zero problems with its private implementation in 
the sense that there has been zero bugs related to it being 
that way.


That is how a Python aficionado would defend the absence of 
visibility attributes therein. "We don't have them, because _ is 
enough, and there are no bugs". And I would agree that D would be 
better off without visibility attributes entirely instead of 
having unending issues with them (private aliases, private + 
reflection, private + synchronized/invariant, etc).


In contrast, I use D every day and love its relaxed attitude 
towards private.


Having class-private doesn't preclude module-private. Dennis even 
submitted a PR implementing class-private, but it stalled because 
people couldn't agree on whether class-private should be "private 
to class" or "private to class instance".







Re: How to reliably detect an alias sequence?

2020-12-27 Thread Max Samukha via Digitalmars-d-learn

On Sunday, 27 December 2020 at 18:25:10 UTC, sighoya wrote:


This should work:
```
static assert(is(int == AliasSeq!int));
Drepl: static assert:  `is(int == (int))` is false
```



That will only work for type tuples. We need a general solution 
that would work for any alias tuple.



The most appropriate solution would be:
```
AliasSeq!int.stringof == (int);
```

But it wouldn't exclude false positives


Yes, stringof is inadequate.




How to reliably detect an alias sequence?

2020-12-27 Thread Max Samukha via Digitalmars-d-learn
Given a name bound to an alias sequence, what is a reliable way 
to detect that?


import std.meta: AliasSeq;

alias a = AliasSeq!int;

static if () {

}

__traits(isSame, a, AliasSeq!a) could work but doesn't, because 
it flattens singletons, which means __traits(isSame, int, 
AliasSeq!int) is true. (A bug/bad design, IMO. If the intended 
behavior is not to flatten tuples passed to __traits, there is no 
reason to make a special case for singletons).


Re: How to get address of a nested function?

2020-11-11 Thread Max Samukha via Digitalmars-d-learn

On Tuesday, 10 November 2020 at 20:13:30 UTC, Daniel Kozak wrote:



non static nested function is a delegate, so you can just 
assign it to delegate like I have posted or you can du this:


import std.stdio;
void main() {
void foo() {
writeln("It works as expected");
}
enum pfoo = 

void delegate() dg;
dg.ptr = pfoo.ptr;
dg.funcptr = pfoo.funcptr;
dg();
}


I need the funcptr at *compile time*, just as I can do "enum p = 
" for a non-static member function.


I wrote "weird" not because '&' returns a delegate, but because I 
was surprised that we can have enum delegates at all, given that 
delegates carry a context pointer, which is not known at compile 
time. That is, the enum delegate appears to be some kind of alias 
of the '&' expression.


Not that the issue is critical, but it makes a library I am 
writing incomplete.


Re: How to get address of a nested function?

2020-11-10 Thread Max Samukha via Digitalmars-d-learn
On Tuesday, 10 November 2020 at 14:36:04 UTC, Steven 
Schveighoffer wrote:




Is there a way to get a pointer to a non-static nested 
function?


I don't think you can do it at compile time. You can at runtime 
by accessing the funcptr of the delegate.


-Steve


Thanks for the reply. I will post the issue to bugzilla.


How to get address of a nested function?

2020-11-10 Thread Max Samukha via Digitalmars-d-learn
We can get the compile time equivalent of a member function's 
address by applying '&' to the function in a static context:


struct S {
void foo() {}
}

enum pfoo =  // ok

void main() {
// now we can use the pointer to create, for example, a 
delegate

S s;
void delegate() dg;
dg.ptr = 
dg.funcptr = pfoo;
dg();
}

However, we can't do that to a nested function:

void main() {
void foo() {
}
enum pfoo =  // weird kind of an enum delegate; 
pfoo.funcptr can't be accessed at compile time.

}

Is there a way to get a pointer to a non-static nested function?


Re: What is the difference between enum and shared immutable?

2020-10-30 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 29 October 2020 at 16:45:51 UTC, Ali Çehreli wrote:



immutable string p;

shared static this() {
  p = environment["PATH"];  // <-- Run time
}



Immutable static variables being implicitly non-thread-local is a 
design mistake. Thread-local immutable variables have the same 
right to exist as immutable class/struct instance fields.


This should be possible without hacks:

immutable int val; // thread-specific value

static this() {
val = ...;
}


...because it is logically the same as:

struct V {
immutable int val;
}

V val;

static this() {
val = V(...);
}


Re: Send empty assoc array to function

2020-07-10 Thread Max Samukha via Digitalmars-d-learn

On Friday, 10 July 2020 at 08:15:24 UTC, Max Samukha wrote:


a unfortunate

an unfortunate





Re: Send empty assoc array to function

2020-07-10 Thread Max Samukha via Digitalmars-d-learn
On Thursday, 9 July 2020 at 21:04:57 UTC, Steven Schveighoffer 
wrote:




Why isn't [] accepted as an empty AA literal?


Because it's an empty dynamic array literal.

If D were to accept an empty AA literal, I'd expect it to be 
[:].


-Steve


Just as typeof(null) is a subtype of all nullable types, you 
could make typeof([]) a subtype of both AAs and dynamic arrays. 
[:] could still be made a specifically AA literal.


BTW, writeln((int[int]).init) prints "[]" (to!string((V[K]).init) 
== "[]"), but pragma(msg, (int[int]).init) - the more general 
'null' ((V[K]).init.stringof == "null"), which is a unfortunate 
inconsistency.


Re: Send empty assoc array to function

2020-07-09 Thread Max Samukha via Digitalmars-d-learn
On Thursday, 9 July 2020 at 20:24:11 UTC, Steven Schveighoffer 
wrote:




Yes, that is correct.

-Steve


Why isn't [] accepted as an empty AA literal?


Re: Send empty assoc array to function

2020-07-09 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 9 July 2020 at 19:53:42 UTC, JN wrote:



foo( [] ) doesn't


Should work in principle, but you can foo(null) to work around.



Re: How to ensure template function can be processed during compile time

2020-07-08 Thread Max Samukha via Digitalmars-d-learn

On Wednesday, 8 July 2020 at 20:11:05 UTC, IGotD- wrote:



Now since mySize is a template, shouldn't this work mySize!v, 
but it doesn't? What essential understanding have I missed here?


You are trying to use a run-time value of v at compile-time, 
which is not possible. If you want the modified size of the type 
of a variable, you can pass the variable to the compile-time 
function by alias:


enum mySize(alias e) = e.sizeof + 42;

int v;
enum size = mySize!v;

pragma(msg, size); // 46LU


If you want to the size of the type of a run-time expression, you 
will have to use typeof:


static assert(mySize!(typeof(v + 1)) == 46);


Re: DMD 2.092 and DIP 25

2020-05-30 Thread Max Samukha via Digitalmars-d-learn

On Saturday, 30 May 2020 at 07:00:07 UTC, Mike Parker wrote:

I find it rather annoying, as I'm returning `const(char)*` and 
not `char*`, but it is what it is. My question is, if I add 
`return` to the function declarations, will this compile all 
the way back to DMD 2.067 *without* `-preview=dip25`? It works 
on 2.091.0. I always assumed a preview feature's syntax wasn't 
supported without the preview switch.


https://run.dlang.io/is/aOZqww

Since  2.067.1: Success and no output


Re: Is it legal to have physical package structure not corresponding to logical one? How to generate .di from that?

2019-09-16 Thread Max Samukha via Digitalmars-d-learn

On Monday, 16 September 2019 at 13:13:50 UTC, Adam D. Ruppe wrote:

On Monday, 16 September 2019 at 07:02:04 UTC, Max Samukha wrote:

[...]


Well, sort of, your code is perfectly legal and has worked 
since the beginning of D. The thing in the spec is referring to 
the assumption the compiler uses to find files not explicitly 
referenced on the build command.


[...]


Thank you, Adam.


Is it legal to have physical package structure not corresponding to logical one? How to generate .di from that?

2019-09-16 Thread Max Samukha via Digitalmars-d-learn

Please consider a project:

src/p2/
|---a.d
|---b.d

in which it is desirable that the logical package tree does not 
fully correspond to the filesystem subtree:


src/p2/a.d:
module p1.p2.a;
...

src/p2/b.d:
module p1.p2.b;
import p1.p2.a;
...

dmd compiles the above structure successfully, even though the 
spec explicitly states that "The packages correspond to directory 
names in the source file path" 
(https://dlang.org/spec/module.html#module_declaration, item 2):


dmd -lib src/p2/a.d src/p2/b.d // ok

Is the spec wrong? Can the current dmd behavior be relied on?


If yes, how does one create an import tree from the structure 
like that?


'dmd -H -o- -Hdimport -op src/p1/a.d src/p2/b.d' is close, but it 
places the .di files into 'import/src/p1' directory (which is 
useless for automatic importing) instead of the expected 
'import/p1/p2'. Is it possible to achieve that without making the 
build process unreasonably complex?





Re: Using CSS Data from Within My Code

2019-09-12 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 12 September 2019 at 09:54:35 UTC, Ron Tarrant wrote:

I found this presented as a solution in a 2016 post:

On Wednesday, 15 June 2016 at 22:05:37 UTC, captaindet wrote:


enum myCSS = q{
GtkNotebook {
background-color: #e9e9e9;
}
GtkNotebook tab {
background-color: #d6d6d6;
}
};


But when I try to use it, I get the following errors:

Warning: C preprocessor directive #e9e9e9 is not supported
Warning: C preprocessor directive #d6d6d6 is not supported

I thought it was odd having 'q' in front of the opening curly 
brace... is this a typo? Shorthand for "string quote"? 
Something like that?


Or do I need to escape these somehow?


q{} is a string that must only contain valid D tokens. D lexer 
does not like C directives. 
https://dlang.org/spec/lex.html#token_strings


Re: How to force an array literal into a read-only data segment?

2019-09-12 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 12 September 2019 at 08:54:09 UTC, a11e99z wrote:
On Thursday, 12 September 2019 at 07:04:19 UTC, Max Samukha 
wrote:


How to achieve the same for an array literal? The closest I 
could come:


enum immutable(int[3]) _tmp = [1, 2, 3];
__gshared a = _tmp.ptr;

Is it possible to force the array into rodata?


https://p0nce.github.io/d-idioms/#Precomputed-tables-at-compile-time-through-CTFE

static immutable(int[3]) _tmp = [1, 2, 3];
?


That looks the same as my example, where 'static' is redundant at 
the module level, and enum just removes the unneeded reference to 
the temporary from the object file. However, __gshared in my 
example does seem to be redundant - 'immutable' implies 
thread-shared in this case.


How to force an array literal into a read-only data segment?

2019-09-12 Thread Max Samukha via Digitalmars-d-learn

test.d:
__gshared t = "text".ptr;


As expected, the "text" literal ends up in a read-only data 
segment, with a pointer to it stored in a writable data segment 
(_TMP0 pointing into .rodata.str1.1):


.data   segment
_D4test1tPya:
dd  offset FLAT:_TMP0@64
db  000h,000h,000h,000h ;
.data   ends

Hex dump of section '.rodata.str1.1':
  0x 74657874 00 text.



How to achieve the same for an array literal? The closest I could 
come:


enum immutable(int[3]) _tmp = [1, 2, 3];
__gshared a = _tmp.ptr;

But the array is still placed into the writable segment:

.data   segment
internal:
db  001h,000h,000h,000h,002h,000h,000h,000h ;
db  003h,000h,000h,000h,000h,000h,000h,000h ;
_D4test1aPyi:
dd  offset FLAT:internal@64
db  000h,000h,000h,000h ;
.data   ends


Is it possible to force the array into rodata?


Re: Learning delegates

2019-09-08 Thread Max Samukha via Digitalmars-d-learn

On Sunday, 8 September 2019 at 10:04:57 UTC, Joel wrote:
I'm trying to understand delegates. Is there any good ways I 
can get a better understanding of them?


You may want to read this: 
https://tour.dlang.org/tour/en/basics/delegates


Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?

2019-09-08 Thread Max Samukha via Digitalmars-d-learn
On Sunday, 8 September 2019 at 09:35:03 UTC, Jonathan M Davis 
wrote:


The C++ support has been improved kind of piecemeal over time, 
and initially, none of it was documented. So, it wasn't exactly 
fully planned out when it was added. IIRC, it was added 
originally so that the dmd frontend could be moved to D. The 
DIP process was very different at that point, and it was much 
more common then for Walter or one of the other core developers 
to just propose a feature in a PR and get it merged. I expect 
that the oddities in the implementation stem from stuff that 
whoever implemented it didn't think to try. The whole process 
is much more rigorous now than it used to be.


- Jonathan M Davis


Good to know, thank you.


Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?

2019-09-08 Thread Max Samukha via Digitalmars-d-learn
On Saturday, 7 September 2019 at 22:19:48 UTC, Jonathan M Davis 
wrote:
On Saturday, September 7, 2019 3:40:58 PM MDT Exil via 
Digitalmars-d-learn wrote:

On Saturday, 7 September 2019 at 17:22:07 UTC, Jonathan M Davis

wrote:
> @safe:
> @system:
>
> then @system overrides @safe.

Just to add onto this, you can't do:

 @safe @system void foo(); // error


but you can do:

 extern(C++, ns1) extern(C++, ns2) void foo(); // ok


It makes no sense to apply multiple namespaces to the same 
symbol. I expect that this behavior is due to a lack of testing 
(the same with the out of order weirdness in the other post). 
It's the sort of thing that you test when you're trying to make 
sure that the feature does the right thing when people use it 
incorrectly, not the sort of thing when you're trying to make 
sure that the feature works as intended, so it's easy to forget.


My guess is that this behavior leaked its way in due to the 
fact that you
need to be able to put multiple extern(C++) declarations on a 
symbol when
you use extern(C++, struct) or extern(C++, class) in addition 
to the

extern(C++) for the namespace.

- Jonathan M Davis


I wonder how that undocumented and not well thought-through (or 
having some unobvious justifications) feature made it into a 
stable release.


Anyway, thank you for your help. I will probably file a bug 
report when I have time.








Should an 'extern(C++, "ns"):' override previous ones in the same scope?

2019-09-07 Thread Max Samukha via Digitalmars-d-learn

extern(C++, "ns1"):
extern(C++, "ns2"): // Not in nested scope. Should it supersede?
void foo();

pragma(msg, foo.mangleof); // _ZN3ns13ns23fooEv instead of 
expected _ZN3ns23fooEv


Is that by design?


Mingling string and identifier namespaces in nested extern(C++) decls

2019-09-07 Thread Max Samukha via Digitalmars-d-learn

extern(C++, "ns1") {
extern(C++, ns2) {
extern(C++, "ns3") {
extern(C++, ns4) {
void foo();
}
}
}
}

pragma(msg, foo.mangleof); // _ZN3ns23ns43ns13ns33fooEv

That produces 'ns2::ns4::ns1::ns3::foo' path instead of the 
intuitively expected 'ns1::ns2::ns3::ns4::foo'. The identifier 
namespaces are grouped before the string ones. Bug or feature?


Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-07 Thread Max Samukha via Digitalmars-d-learn
On Saturday, 7 September 2019 at 13:01:38 UTC, Jacob Carlborg 
wrote:

On 2019-09-06 21:03, Max Samukha wrote:

Is there any practical use of having identically named .d and 
.di alongside?


Same as in C/C++. This allows you to have a header file if you 
want to distribute a closed source library.


I know, but I have never seen a D project that would generate 
headers into the source directory. C++ requires headers for 
sharing declarations with other translation units in the project, 
even if the headers are not intended for distribution. That is 
why having headers alongside implementations is a common case 
there. D doesn't require that.


Anyway, that's a minor concern. Thank you.


Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

On Friday, 6 September 2019 at 17:54:51 UTC, Adam D. Ruppe wrote:

On Friday, 6 September 2019 at 17:42:08 UTC, Max Samukha wrote:
That file was silently imported by the compiler (probably, a 
bug).


That's by design - the automatic module import lookups actually 
always look for .di file first, then .d files.


Is there any practical use of having identically named .d and .di 
alongside?


Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

On Friday, 6 September 2019 at 16:55:31 UTC, Max Samukha wrote:

On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote:



If that is happening you hit a bug.
It seems unlikely though.


Could you elaborate a bit? How should extern(C/C++) definitions 
be mangled - fully qualified or not, and why is the reference 
to extern(C/C++) D-mangled? The spec seems to say nothing about 
it.


Ok, I have figured it out. There was 'a.di' file along with 'a.d' 
in the same directory, with a definition of extern(D) foo. That 
file was silently imported by the compiler (probably, a bug). 
Thank you for your attention.






Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote:

On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:

Consider the following two modules:

1. test.d:

module test;

import lib.a;

void main() {
foo();
}


2. lib/a.d:

module lib.a;

extern(C) void foo() {}


When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the 
function in 'a.o' is mangled as 'foo', but the reference in 
'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a 
link error. I would expect both of them to be either plain C 
mangling, or fully qualified D (better). What is the reason 
for current behavior?


If that is happening you hit a bug.
It seems unlikely though.


Could you elaborate a bit? How should extern(C/C++) definitions 
be mangled - fully qualified or not, and why is the reference to 
extern(C/C++) D-mangled? The spec seems to say nothing about it.




Re: Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

On Friday, 6 September 2019 at 15:32:07 UTC, 0xEAB wrote:

On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:

Consider the following two modules:


What compiler version are you using?


DMD64 D Compiler v2.088.0-1-g4011382ea, linux


Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

Consider the following two modules:

1. test.d:

module test;

import lib.a;

void main() {
foo();
}


2. lib/a.d:

module lib.a;

extern(C) void foo() {}


When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the 
function in 'a.o' is mangled as 'foo', but the reference in 
'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link 
error. I would expect both of them to be either plain C mangling, 
or fully qualified D (better). What is the reason for current 
behavior?


Why are constructor definitions are preserved in interface files?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

module lib.a;

class C {

this() {
}

void foo() {
}

~this() {
}

}


dmd -H -o- a.d:

// D import file generated from 'a.d'
module lib.a;
class C
{
this()
{
}
void foo();
~this();
}

The destructor and member function definitions have been removed 
as expected. What is the reason for keeping the constructor 
definition?




Why are constructor definitions preserved in interface files?

2019-09-06 Thread Max Samukha via Digitalmars-d-learn

module lib.a;

class C {

this() {
}

void foo() {
}

~this() {
}

}


dmd -H -o- a.d:

// D import file generated from 'a.d'
module lib.a;
class C
{
this()
{
}
void foo();
~this();
}

The destructor and member function definitions have been removed 
as expected. What is the reason for keeping the constructor 
definition?




How to get the type of a derived class in a method of its base class?

2017-02-18 Thread Max Samukha via Digitalmars-d-learn

class A {
this(T = this)() {
static assert(is(T == B));
}
}

class B {
}

auto b = new B;

Here, T becomes A, which may be reasonable but is completely 
useless. Is there a way to obtain the type of the class (or class 
instance reference) the method is called on?


Re: Why aren't overloaded nested functions allowed?

2016-05-31 Thread Max Samukha via Digitalmars-d-learn

On Tuesday, 31 May 2016 at 11:54:40 UTC, Timon Gehr wrote:

On 30.05.2016 18:22, Max Samukha wrote:
 From the spec (https://dlang.org/spec/function.html#nested): 
"Nested

functions cannot be overloaded."

Anybody knows what's the rationale?


The rationale is that nobody has implemented it in DMD.
https://issues.dlang.org/show_bug.cgi?id=12578


Ah, that "seems pointless" argument again.


Re: Why aren't overloaded nested functions allowed?

2016-05-31 Thread Max Samukha via Digitalmars-d-learn

On Monday, 30 May 2016 at 23:17:15 UTC, pineapple wrote:

On Monday, 30 May 2016 at 16:22:26 UTC, Max Samukha wrote:
From the spec (https://dlang.org/spec/function.html#nested): 
"Nested functions cannot be overloaded."


Anybody knows what's the rationale?


I'm guessing it's related to -

Unlike module level declarations, declarations within function 
scope are processed in order.


And I'd suspect that the cleanest solution would be similar to 
the one given for interdependent functions: Declare the nested 
functions in a static nested struct instead.


Ok, thanks.



Why aren't overloaded nested functions allowed?

2016-05-30 Thread Max Samukha via Digitalmars-d-learn
From the spec (https://dlang.org/spec/function.html#nested): 
"Nested functions cannot be overloaded."


Anybody knows what's the rationale?


Re: D, GTK, Qt, wx,…

2016-05-29 Thread Max Samukha via Digitalmars-d-learn

On Sunday, 29 May 2016 at 11:03:36 UTC, Russel Winder wrote:



From what I can tell QtD is in need of effort or restarting.


I will probably give it another shot when D has better interop 
with C++. Particularly, when multiple inheritance of C++ 
interfaces is implemented, Walter admits that mingling C++ 
namespaces into D name hierarchy is a horrible idea, and so on.




Weird "nested function cannot be accessed" error

2016-05-29 Thread Max Samukha via Digitalmars-d-learn

This code fails to compile:

void bar(alias f)() {
f();
}

void foo(alias f)() {
bar!f();
}

void main() {
void f()() {
}
foo!f();
}

Error: function test.main.f!().f is a nested function and cannot 
be accessed from test.bar!(f).bar



But non-template nested functions are accepted:

void main() {
void f() {
}
foo!f(); // ok
}


What's going on here?


Re: C header file: tagged enumerations

2016-04-27 Thread Max Samukha via Digitalmars-d-learn

On Tuesday, 26 April 2016 at 22:57:36 UTC, Jesse Phillips wrote:


typedef enum tagINSTALLMESSAGE
{
// 12 others ...
INSTALLMESSAGE_INITIALIZE ,
INSTALLMESSAGE_TERMINATE  ,
INSTALLMESSAGE_SHOWDIALOG ,
#if (_WIN32_MSI >= 500)
INSTALLMESSAGE_PERFORMANCE,
#endif // (_WIN32_MSI >= 500)
#if (_WIN32_MSI >= 400)
INSTALLMESSAGE_RMFILESINUSE   ,
#endif // (_WIN32_MSI >= 400)
#if (_WIN32_MSI >= 450)
INSTALLMESSAGE_INSTALLSTART   ,
INSTALLMESSAGE_INSTALLEND ,
#endif // (_WIN32_MSI >= 450)
} INSTALLMESSAGE;


enum _WIN32_MSI = 450;

mixin((int _WIN32_MSI = _WIN32_MSI) {
string r ="enum INSTALLMESSAGE {
INSTALLMESSAGE_INITIALIZE,
INSTALLMESSAGE_TERMINATE,
INSTALLMESSAGE_SHOWDIALOG,";
if (_WIN32_MSI >= 500)
r ~= "INSTALLMESSAGE_PERFORMANCE,";
if (_WIN32_MSI >= 400)
r ~= "INSTALLMESSAGE_RMFILESINUSE   ,";
if (_WIN32_MSI >= 450) {
r ~= "INSTALLMESSAGE_INSTALLSTART   ,
  INSTALLMESSAGE_INSTALLEND ,";
}
return r ~ "}";
}());


))) // sardonic laugh, which is not part of the source





Re: Patterns for functions in template parameters

2014-10-24 Thread Max Samukha via Digitalmars-d-learn

On Friday, 24 October 2014 at 08:53:05 UTC, Kagamin wrote:

maybe
template Foo(T a, T: T[U], U)


No luck. Error: undefined identifier T


Re: Patterns for functions in template parameters

2014-10-24 Thread Max Samukha via Digitalmars-d-learn
On Friday, 24 October 2014 at 14:13:10 UTC, ketmar via 
Digitalmars-d-learn wrote:


sorry if this is not what you mean, template magic sometimes 
scares me

and i'm loosing my mind. ;-)


What I meant was your example with the delegate parameter moved 
to the template list:


template Foo(T delegate(U) a, T, U) {}
Foo!((int x) = true); // T == bool, U == int


Or generalized to functions (and maybe functors in the 
unfortunate C++ sense):


template Foo(T(U) a, T, U) {}


Apparently, D doesn't allow type variables in value parameters at 
all.
















Re: Patterns for functions in template parameters

2014-10-24 Thread Max Samukha via Digitalmars-d-learn

On Friday, 24 October 2014 at 17:08:00 UTC, Max Samukha wrote:

Apparently, D doesn't allow type variables in value parameters 
at all.


Nor does it allow passing delegates to value parameters, only 
alias parameters.




Patterns for functions in template parameters

2014-10-23 Thread Max Samukha via Digitalmars-d-learn
If I remember correctly, at some point a syntax was introduced 
for pattern-matching functions passed to templates. Something 
like:


template Foo(B(A) foo, A, B)
{
}

alias f = Foo!((int x) = x % 2 == 0);

That would instantiate Foo with B == bool, A == int and foo bound 
to the lambda.


The compiler has rejected all syntax variations I have tried and 
the specs is not helpful. Does anybody know if the feature exists 
and what is the syntax exactly?


Re: Patterns for functions in template parameters

2014-10-23 Thread Max Samukha via Digitalmars-d-learn

On Thursday, 23 October 2014 at 11:25:01 UTC, Kagamin wrote:

Maybe, argument deduction?

template Foo(T: T[U], U)
{
...
}

Foo!(int[long])  // instantiates Foo with T set to int, U set 
to long


Yes, but for a value template parameter.

template Foo(int[long] a);
{
}
Foo!([1: 2]); // ok, this passes.


Now I'd like to loosen the template so it accepts AAs of any type:

template Foo(T[U] a /* forall T, U */)
{
}


And then unary functions of any type:

template Foo(T a(U) /* forall T, U */)
{
}


In other words, to move the run-time parameter below to the 
template parameter list:


void foo(T, U)(T delegate(U) a)
{
}


Or in other other words (for any callables):

template Foo(alias a) if (isCallable!a  ParameterTypes!a.length 
== 1)

{
alias T = ReturnType!a;
alias U = ParameterTypes!a[0];
}


I vaguely remember some syntax tweaks were introduced, presumably 
for that effect. Trying to find out what they were exactly. I 
might have dreamt it as well.