Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 01:46:30 UTC, Chameleon wrote:

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:



Here is my solution that does not solve problem 2:


import std.stdio;

[...]



this is not programming. this is witchcraft!



Just call me Dandalf the D Slayer!

At least I finally got it to work. It's terrible that I have to 
use import and read the file in directly to do this ;/ It is 
working though.


Re: Build interface from abstract class

2018-05-29 Thread Chameleon via Digitalmars-d-learn

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:



Here is my solution that does not solve problem 2:


import std.stdio;

[...]



this is not programming. this is witchcraft!



Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 20:53:14 UTC, DigitalDesigns wrote:

On Tuesday, 29 May 2018 at 20:26:52 UTC, arturg wrote:

On Tuesday, 29 May 2018 at 19:06:24 UTC, DigitalDesigns wrote:

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class 
needs the interface defined. I need to be able to forward 
define the interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}



would it work if you define the interface but mixin the 
members?


interface A
{
mixin(InterfaceFromClass!C);
}


Yes, I made a post about it but it didn't get through or I 
forgot to send ;/


Doing it this way solves the original problems but creates a 
new problem in that any class that inherits from an abstract 
class that implements A doesn't work.


interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B : A
{
A foo() { return this; }
int bar() { return 3; }
}


class C : B
{
// compiler says foo, bar not implemented
}


so, instead

interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B
{
A foo() { return this; } // requires cast
int bar() { return 3; }
}


class C : B, A
{

}


works but requires casting this in B which happens to work in 
C. So It is a fessible solution but I'm not sure why the 
compiler things the first case doesn't implement the methods 
when it clearly does. I think it looks at A and doesn't compute 
the mixin first when parsing C because if I put the output of 
the mixin directly it works. Probably a bug...




This method, which imports the source code and extracts the 
members works but is very fragile and requires using -J:




// Directly copies the data to the interface with a few hacks to 
fix the bug from the original, it excepts a well formatted input



template InterfaceFromClass(alias T)
{

string InterfaceFromClass(string file = __FILE_FULL_PATH__)()
{
string res;
import std.path, std.string, std.algorithm;
enum data = import(file.baseName);
enum mc = "abstract class "~T.stringof~" : ";
enum im = `@("InterfaceMembers")`;
int level = 0;
auto baseIndentLevel = -1;
int funcIndentLevel = -1;
foreach(v; data.splitLines)
{
string l = v;
auto indentLevel = l.length - l.stripLeft().length;
auto ll = l.strip();
if (ll.length == 0) continue;

			//res ~= to!string(l.length) ~"\n" ~ l[0..min(mc.length, 
l.length)] ~ "\n";
			if (level == 0 && ll.length >= mc.length && 
ll[0..min(mc.length, ll.length)] == mc) { baseIndentLevel = 
indentLevel; level = 1; continue; }	// Finds "abstract class  
: "
			if (level == 1 && ll.length >= im.length && 
ll[0..min(im.length, ll.length)] == im) { level = 2; continue; 
}	// Finds "@("InterfaceMembers))" near by

if (level >= 2 && l == "}") break;
if (level == 2 && ll.length > 1)
{
if (funcIndentLevel < 0) funcIndentLevel = 
indentLevel;
if (funcIndentLevel < indentLevel) continue;

// A simple function definition(ends with a 
');')
if (!ll.canFind("=") && l.length > 2 && l[$-2..$] == ");") { 
res ~= l ~ "\n"; continue; }

// ignore fields(assumes it has no {, } but 
ends with a ';')
if (!ll.canFind("{") && l[$-1] == ';' && ll[$-2..$] != "};") 
continue;


// ignore functions with inline blocks
if (ll.canFind(") {")) { l = l[0..$ - ll.find(") {").length] 
~ ")"; }


// must get function signature only(ignore 
body)
res ~= l ~ ((ll[$] != ';') ? ";" : "") ~ "\n";

}
}


return res;
}
}


Why the original code is being broke by using D's traits to build 
the functions properly is beyond me. I'm pretty sure it is a bug 
given the example I gave earlier.





Re: Getter an lvalue and cannot be modified

2018-05-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/27/18 5:23 AM, IntegratedDimensions wrote:

C[] c;
@property C[] get() { return c; }

get ~= something;

errors out, yet

auto q = get;
q ~= something;

is fine.


It's "fine", but not doing what you may expect.

This appends an element to q, but does nothing to c.

While an array is not exactly a value type, it's also not exactly a 
reference type. This is why the compiler complains -- your original code 
will append an element and then throw that addition away.


Why is D thinking that ~= is being applied to get, the function, rather 
than what it returns?


When I try this, it says "get() is not an lvalue and cannot be 
modified", which seems to indicate that the expression get() (meaning 
what it returns) is not an lvalue. While it's a bit ambiguous in this 
case, a more complicated expression would be self-explanatory. Maybe the 
error message could be prepended with 'the expression' to make it clearer.


When I converted a field in to a property, an AA, it is returning null 
rather than being initialized by default.


AAs are initialized as null, not sure what you are expecting here? An 
example may clear things up.


Seems like properties are 
broke. I'd expect a property getter to behave, for all intents and 
purposes as if it were field. I shouldn't have to have a temp variable 
to be able to use it as such.


You don't normally, but if you want to treat it as an lvalue, 
unfortunately, you do.


The workaround is to spell things out:

prop = prop + 1; // instead of prop += 1

But this doesn't work in all cases.

-Steve


Re: full path to source file __FILE__

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 21:41:37 UTC, Ali Çehreli wrote:

On 05/29/2018 02:34 PM, DigitalDesigns wrote:
 > auto x(string fp = __FULL_FILE_PATH__)()

{
    pragma(msg, fp);
}

?


__FILE_FULL_PATH__

  https://dlang.org/spec/expression#specialkeywords

Ali


Lol, thanks:




Re: full path to source file __FILE__

2018-05-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/29/18 5:34 PM, DigitalDesigns wrote:

On Wednesday, 27 July 2016 at 13:58:22 UTC, Jonathan Marler wrote:

On Thursday, 21 July 2016 at 19:54:34 UTC, Jonathan Marler wrote:
Is there a way to get the full path of the current source file? 
Something like:


__FILE_FULL_PATH__

I'm asking because I'm rewriting a batch script in D, meant to be ran 
with rdmd.  However, the script needs to know it's own path.  The 
original batch script uses the %~dp0 variable for this, but I'm at a 
loss on how to do this in D.  Since rdmd compiles the executable to 
the %TEMP% directory, thisExePath won't work.


BATCH
-
echo "Directory of this script is " %~dp0


DLANG
-
import std.stdio;
int main(string[] args) {
    writeln("Directory of this script is ", ???);
}


For others who may see this thread, the __FULL_FILE_PATH__ special 
trait was added to the dmd compiler with this PR: 
https://github.com/dlang/dmd/pull/5959


At the time of this post, the latest released version of D is 2.071.1, 
so this trait should be available on any release after that.


Except it doesn't?

auto x(string fp = __FULL_FILE_PATH__)()
{
    pragma(msg, fp);
}

?


__FILE_FULL_PATH__, not __FULL_FILE_PATH__ (yes, it was wrong in the 
post you quoted).


In addition, you must instantiate the template:

void main()
{
x();
}

-Steve


Re: full path to source file __FILE__

2018-05-29 Thread Ali Çehreli via Digitalmars-d-learn

On 05/29/2018 02:34 PM, DigitalDesigns wrote:
 > auto x(string fp = __FULL_FILE_PATH__)()

{
    pragma(msg, fp);
}

?


__FILE_FULL_PATH__

  https://dlang.org/spec/expression#specialkeywords

Ali


Re: full path to source file __FILE__

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 27 July 2016 at 13:58:22 UTC, Jonathan Marler wrote:
On Thursday, 21 July 2016 at 19:54:34 UTC, Jonathan Marler 
wrote:
Is there a way to get the full path of the current source 
file? Something like:


__FILE_FULL_PATH__

I'm asking because I'm rewriting a batch script in D, meant to 
be ran with rdmd.  However, the script needs to know it's own 
path.  The original batch script uses the %~dp0 variable for 
this, but I'm at a loss on how to do this in D.  Since rdmd 
compiles the executable to the %TEMP% directory, thisExePath 
won't work.


BATCH
-
echo "Directory of this script is " %~dp0


DLANG
-
import std.stdio;
int main(string[] args) {
writeln("Directory of this script is ", ???);
}


For others who may see this thread, the __FULL_FILE_PATH__ 
special trait was added to the dmd compiler with this PR: 
https://github.com/dlang/dmd/pull/5959


At the time of this post, the latest released version of D is 
2.071.1, so this trait should be available on any release after 
that.


Except it doesn't?

auto x(string fp = __FULL_FILE_PATH__)()
{
   pragma(msg, fp);
}

?


string mixin output works when directly used but when generator is used D fails

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

https://dpaste.dzfl.pl/67691db19ce8

Just delete 9 to 29 for the code to work. Note that none of the 
code effects the output but D gives strange errors. In my code it 
says the interface members are not implemented(which they are)


foreach (member; __traits(allMembers, T))
{
static foreach (overload; MemberFunctionsTuple!(T, 
member))
{
static if (__traits(getProtection, __traits(getMember, T, 
member)) == "public")

{
foreach(a; __traits(getAttributes, 
overload))
		static if (is(typeof(a) == string) && a.length > 0 && a == 
"InterfaceMembers")

{   
string q;
foreach(b; 
__traits(getAttributes, overload))
static if (is(typeof(b) == string) && b.length > 0 && b 
== "InterfaceMembers")


continue;
else
q ~= 
"@("~b.stringof~") ";

//s ~= 
"\t"~q~cloneFunction!(overload, T) ~ ";\n";
}
}
}
}

is somehow breaking the interface. It should have no effect on it 
at all. Seems like a bug to me.


Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 20:26:52 UTC, arturg wrote:

On Tuesday, 29 May 2018 at 19:06:24 UTC, DigitalDesigns wrote:

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class 
needs the interface defined. I need to be able to forward 
define the interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}



would it work if you define the interface but mixin the members?

interface A
{
mixin(InterfaceFromClass!C);
}


Yes, I made a post about it but it didn't get through or I forgot 
to send ;/


Doing it this way solves the original problems but creates a new 
problem in that any class that inherits from an abstract class 
that implements A doesn't work.


interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B : A
{
A foo() { return this; }
int bar() { return 3; }
}


class C : B
{
// compiler says foo, bar not implemented
}


so, instead

interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B
{
A foo() { return this; } // requires cast
int bar() { return 3; }
}


class C : B, A
{

}


works but requires casting this in B which happens to work in C. 
So It is a fessible solution but I'm not sure why the compiler 
things the first case doesn't implement the methods when it 
clearly does. I think it looks at A and doesn't compute the mixin 
first when parsing C because if I put the output of the mixin 
directly it works. Probably a bug...


Re: Build interface from abstract class

2018-05-29 Thread arturg via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 19:06:24 UTC, DigitalDesigns wrote:

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class 
needs the interface defined. I need to be able to forward 
define the interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}



would it work if you define the interface but mixin the members?

interface A
{
mixin(InterfaceFromClass!C);
}


Re: How do I break from loop when using parallel()?

2018-05-29 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2018-05-28 at 21:04 +, Dr.No via Digitalmars-d-learn wrote:
>   import std.parallelism : parallel;
>   foreach(t; parallel(arr))
>   {
>   if(!doSomething(t)) {
>   return false;
>   }
>   }
> 
> It reuturns the run time error:
> 
> > std.parallelism.ParallelForeachError@(0): Cannot break from a 
> > parallel foreach loop using break, return, labeled 
> > break/continue or goto statements.
> 
> What's the proper way to break from loop?

It isn't a loop, it is a task scatter/gather, with each task running to
completion independent of all other tasks. Thus the concept of
break/return doesn't exist.

It could be argued that this is a bad use of foreach, but it is what it
is.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class needs 
the interface defined. I need to be able to forward define the 
interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}

I could see that D wants A so it can have the complete picture 
for B, but this is one of those problems where it shouldn't 
matter.



This requires hoops and ultimately does not solve the problem. 
Any time A is used it will be treated as undefined by the 
compiler and throw an error.


For example:




pragma(msg, InterfaceFromClass!(C, "A"));

mixin(InterfaceFromClass!(C, "A"));

interface B : A
{

}

abstract class C
{
@("InterfaceMembers")
{
int xe = 3;
@(3) void foo() { }

@property int x() { return 3; };

B bar() { return null; }
}

}

abstract class D : C, B
{

}

fails because C.bar returns a B, which has not yet fully been 
defined because A has not yet fully been defined. Now, if I could 
just get the function signature without using the type system, 
this wouldn't be a problem. I don't really care if B is defined 
yet, I just need to know it's name. I guess D tries to enforce 
consistency at all steps, which is a problem here because C uses 
a yet to be defined type, even though it will be defined soon 
enough without problems.


One of the main culprits is isCallable which is what errors out 
because of the yet to be defined B.


So, I guess some other method will have to work.




Re: Native PDB Error

2018-05-29 Thread Begah via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 07:53:49 UTC, rikki cattermole wrote:

On 29/05/2018 7:47 PM, Begah wrote:
I have recently reinstalled a fresh version of Windows 10. I 
installed DMD 1.9.0 and compiled my code ( that was compiling 
before reinstalling Windows ).


What?

That is definitely not a valid dmd version for D2.


Sorry, that was the dub version. I ment 2.080.0


Re: Native PDB Error

2018-05-29 Thread rikki cattermole via Digitalmars-d-learn

On 29/05/2018 7:47 PM, Begah wrote:
I have recently reinstalled a fresh version of Windows 10. I installed 
DMD 1.9.0 and compiled my code ( that was compiling before reinstalling 
Windows ).


What?

That is definitely not a valid dmd version for D2.


Native PDB Error

2018-05-29 Thread Begah via Digitalmars-d-learn
I have recently reinstalled a fresh version of Windows 10. I 
installed DMD 1.9.0 and compiled my code ( that was compiling 
before reinstalling Windows ).

I get this error at the linking phase :
Native PDB Error: The entry already exists.  The specified module 
already exists


I made a simplified project that gets the same error :

import imageformats;
import derelict.glfw3;

void main() {
IFImage i0;
}

and dub.json :
"dependencies": {
"derelict-glfw3": "4.0.0-beta.1",
"imageformats": "~>7.0.0"
}

Compiling for 32-bit works.
Compiling for 64-bit gives that error : dub --arch=x86_64
Changing imageformats version to 5.2.0 compiles but any higher 
doesn't.
I tried compiling the code with and without admin privileges but 
it doesn't do anything.
I know that PDB is used for debugging but I don't understand this 
error.

Any ideas?