Re: no size yet for forward reference for nested structures

2015-01-16 Thread Steven Schveighoffer via Digitalmars-d

On 1/16/15 2:18 AM, zeljkog wrote:

On 16.01.15 08:04, zeljkog wrote:

On 15.01.15 23:30, Steven Schveighoffer wrote:

On 1/15/15 9:56 AM, zeljkog wrote:

This compiles:

import std.container;

class Node
{
DList!Node children;
}



Then use DList?

DList is not SList, they were written by different people.

-Steve


SList.Range has moveFront, DList.Range does not.

If I comment out SList.Range.moveFront, it compiles with SList.


And yes, looks like hasAliasing!Node (from std.algorithm.move) is only
problem.


I think this is likely the issue. std.algorithm.move should not have to 
care what is inside a class to move a reference to it.


I will file a bug. Thanks for digging into this.

-Steve


Re: no size yet for forward reference for nested structures

2015-01-16 Thread Steven Schveighoffer via Digitalmars-d

On 1/16/15 1:24 PM, Steven Schveighoffer wrote:


I will file a bug. Thanks for digging into this.


https://issues.dlang.org/show_bug.cgi?id=13990
https://github.com/D-Programming-Language/phobos/pull/2876

-Steve


Re: no size yet for forward reference for nested structures

2015-01-15 Thread Ali Çehreli via Digitalmars-d

On 01/15/2015 06:56 AM, zeljkog wrote:

This compiles:

import std.container;

class Node
{
DList!Node children;
}



So does using an 'interface', which may be more desirable in some cases:

import std.container;

interface Iface
{}

class Node : Iface
{
SList!Iface children;
}

void main()
{
auto n = new Node();
}

Ali



Re: no size yet for forward reference for nested structures

2015-01-15 Thread zeljkog via Digitalmars-d
This compiles:

import std.container;

class Node
{
   DList!Node children;
}


Re: no size yet for forward reference for nested structures

2015-01-15 Thread Steven Schveighoffer via Digitalmars-d

On 1/15/15 9:56 AM, zeljkog wrote:

This compiles:

import std.container;

class Node
{
DList!Node children;
}



Then use DList?

DList is not SList, they were written by different people.

-Steve


Re: no size yet for forward reference for nested structures

2015-01-15 Thread zeljkog via Digitalmars-d

On 15.01.15 23:30, Steven Schveighoffer wrote:

On 1/15/15 9:56 AM, zeljkog wrote:

This compiles:

import std.container;

class Node
{
DList!Node children;
}



Then use DList?

DList is not SList, they were written by different people.

-Steve


SList.Range has moveFront, DList.Range does not.

If I comment out SList.Range.moveFront, it compiles with SList.


Re: no size yet for forward reference for nested structures

2015-01-15 Thread zeljkog via Digitalmars-d

On 16.01.15 08:04, zeljkog wrote:

On 15.01.15 23:30, Steven Schveighoffer wrote:

On 1/15/15 9:56 AM, zeljkog wrote:

This compiles:

import std.container;

class Node
{
DList!Node children;
}



Then use DList?

DList is not SList, they were written by different people.

-Steve


SList.Range has moveFront, DList.Range does not.

If I comment out SList.Range.moveFront, it compiles with SList.


And yes, looks like hasAliasing!Node (from std.algorithm.move) is only 
problem.


Re: no size yet for forward reference for nested structures

2015-01-15 Thread Steven Schveighoffer via Digitalmars-d

On 1/14/15 10:09 AM, Ali Çehreli wrote:

On 01/14/2015 02:53 AM, ketmar via Digitalmars-d wrote:

  On Wed, 14 Jan 2015 10:41:07 +
  qqiang via Digitalmars-d digitalmars-d@puremagic.com wrote:
 
  template PowerHeap(T) {
import std.container : SList;
 
private alias PowerForest = SList!PowerNode;
 
private final class PowerNode {
private {
T payload_;
uint rank_;
PowerForest children_;
}
}
 
final class PowerHeap {
private {
PowerNode top_;
PowerForest forest_;
uint size_;
}
}
  }
 
  unittest {
PowerHeap!int h;
  }
  there is a circular dependency in your data structures. you're defining
  `PowerNode` in the terms of... `PowerNode`. this won't work.
 
  your `PowerForest` definition depends of complete `PowerNode`
  definition, but `PowerNode` definition depends of complete
  `PowerForest` definition.
 
  don't do that.
 

Reduced:

import std.container;

class Node
{
 SList!Node children;
}

void main()
{}

Error: class deneme.Node no size yet for forward reference

I wonder why an SList of a reference type requires the size of the
elements? The following compiles but is that a pointer to a class
variable or a class object? How can we even use the 'children' member?

 SList!(Node*) children;

Ali



In my not-so-expert opinion, I think this is somewhat of a bug, but not 
in the compiler. Note that it depends heavily on the definition of 
SList. If SList starts using pieces of S, it may confuse or create 
issues with the compiler.


A simple test is to declare an opaque class:

class S;

void main()
{
   S foo;
}

This works (at least it works to compile, not to link as the linker 
can't find the class symbol)


Now, if I do this:

import std.container;

class S;

alias listofs = SList!S;

void main()
{
   S foo;
}

I get the following audit from the compiler:

/usr/share/dmd/src/phobos/std/traits.d(2032): Error: class testforward.S 
unknown size
/usr/share/dmd/src/phobos/std/traits.d(2198): Error: template instance 
std.traits.FieldTypeTuple!(S) error instantiating
/usr/share/dmd/src/phobos/std/traits.d(2349):instantiated from 
here: RepresentationTypeTuple!(S)
/usr/share/dmd/src/phobos/std/traits.d(2692):instantiated from 
here: hasRawAliasing!(S)
/usr/share/dmd/src/phobos/std/algorithm.d(1888):instantiated 
from here: hasAliasing!(S)
/usr/share/dmd/src/phobos/std/container.d(1008): Error: template 
instance std.algorithm.move!(S) error instantiating

testforward.d(4):instantiated from here: SList!(S)
/usr/share/dmd/src/phobos/std/range.d(3149): Error: template instance 
std.range.hasAssignableElements!(Range) error instantiating
/usr/share/dmd/src/phobos/std/container.d(1359): Error: template 
instance std.range.Take!(Range) error instantiating

testforward.d(4):instantiated from here: SList!(S)


So I think it's SList's invocation of move, which in turn checks 
hasAliasing, which in turn needs S's total definition (as it starts 
getting the fields of S). I think hasAliasing!(someclass) needs to be 
short circuited to true, or slist needs to use some other mechanism. I 
don't know how SList works exactly, maybe it does not actually allocate 
a list of class references, but instead emplaces them. In that case, you 
may be out of luck.


-Steve


Re: no size yet for forward reference for nested structures

2015-01-14 Thread Ali Çehreli via Digitalmars-d

On 01/14/2015 07:39 AM, ketmar via Digitalmars-d wrote:

On Wed, 14 Jan 2015 07:09:44 -0800
Ali Çehreli via Digitalmars-d digitalmars-d@puremagic.com wrote:


Reduced:

import std.container;

class Node
{
  SList!Node children;
}

void main()
{}

Error: class deneme.Node no size yet for forward reference

I wonder why an SList of a reference type requires the size of the
elements? The following compiles but is that a pointer to a class
variable or a class object? How can we even use the 'children' member?

  SList!(Node*) children;


i don't know: i've never used `std.container` anyway. ;-)



It looks like this came up not too long ago:


http://forum.dlang.org/thread/akkrerlsjutdfmzsw...@forum.dlang.org#post-akkrerlsjutdfmzswsbo:40forum.dlang.org

I think this is a bug but I will wait for others to confirm.

Ali



Re: no size yet for forward reference for nested structures

2015-01-14 Thread Ali Çehreli via Digitalmars-d

On 01/14/2015 02:53 AM, ketmar via Digitalmars-d wrote:

 On Wed, 14 Jan 2015 10:41:07 +
 qqiang via Digitalmars-d digitalmars-d@puremagic.com wrote:

 template PowerHeap(T) {
   import std.container : SList;

   private alias PowerForest = SList!PowerNode;

   private final class PowerNode {
   private {
   T payload_;
   uint rank_;
   PowerForest children_;
   }
   }

   final class PowerHeap {
   private {
   PowerNode top_;
   PowerForest forest_;
   uint size_;
   }
   }
 }

 unittest {
   PowerHeap!int h;
 }
 there is a circular dependency in your data structures. you're defining
 `PowerNode` in the terms of... `PowerNode`. this won't work.

 your `PowerForest` definition depends of complete `PowerNode`
 definition, but `PowerNode` definition depends of complete
 `PowerForest` definition.

 don't do that.


Reduced:

import std.container;

class Node
{
SList!Node children;
}

void main()
{}

Error: class deneme.Node no size yet for forward reference

I wonder why an SList of a reference type requires the size of the 
elements? The following compiles but is that a pointer to a class 
variable or a class object? How can we even use the 'children' member?


SList!(Node*) children;

Ali



Re: no size yet for forward reference for nested structures

2015-01-14 Thread ketmar via Digitalmars-d
On Wed, 14 Jan 2015 07:09:44 -0800
Ali Çehreli via Digitalmars-d digitalmars-d@puremagic.com wrote:

 Reduced:
 
 import std.container;
 
 class Node
 {
  SList!Node children;
 }
 
 void main()
 {}
 
 Error: class deneme.Node no size yet for forward reference
 
 I wonder why an SList of a reference type requires the size of the 
 elements? The following compiles but is that a pointer to a class 
 variable or a class object? How can we even use the 'children' member?
 
  SList!(Node*) children;

i don't know: i've never used `std.container` anyway. ;-)


signature.asc
Description: PGP signature


Re: no size yet for forward reference for nested structures

2015-01-14 Thread bearophile via Digitalmars-d

qqiang:

I've googled and found no straightforward solution to this 
issue. The how can I modify my code to eliminate this error?


Your code gives me a different error (Error: PowerHeap!int is 
used as a type).


What if you replace the SList with a dynamic array?

Bye,
bearophile


Re: no size yet for forward reference for nested structures

2015-01-14 Thread Ali Çehreli via Digitalmars-d
First a reminder that this sort of question is more suitable to the 
D.learn newsgroup.


On 01/13/2015 10:41 PM, qqiang wrote:

 The following code:
 ```D
 template PowerHeap(T) {
  import std.container : SList;

  private alias PowerForest = SList!PowerNode;

  private final class PowerNode {
  ...
  }

  final class PowerHead {
  ...
  }
 }

 unittest {
  PowerHeap!int h;
 }
 ```

I started with your code and produced the following one:

template PowerHeap(T) {
import std.container : SList;

private alias PowerForest = SList!PowerNode;

private final class PowerNode {
// ...
}

final class PowerHead {
// ...
}
}

unittest {
PowerHeap!int h;// -- Compilation error here
}

void main()
{}

 failed to compile and get the error: PowerHeap!int.PowerNode: no size
 yet for forward reference.

What compiler and version are you using? I received a different error 
with the git head dmd:


  Error: PowerHeap!int is used as a type

The compiler is right, PowerHeap!int is a template instantiation that 
wraps a number of definitions. Did you mean one of those? The following 
compiles:


unittest {
PowerHeap!int.PowerHead h;// -- now compiles
}

 I've googled and found no straightforward solution to this issue. The
 how can I modify my code to eliminate this error?

Please provide exact code so that... Oh, wait! I've just noticed that 
your error message has PowerHeap!int.PowerNode in it. Let me try with that:


unittest {
PowerHeap!int.PowerNode h;// -- this compiles as well
}

Yeah, please provide exact code. :)

Ali



Re: no size yet for forward reference for nested structures

2015-01-14 Thread ketmar via Digitalmars-d
On Wed, 14 Jan 2015 10:41:07 +
qqiang via Digitalmars-d digitalmars-d@puremagic.com wrote:

 template PowerHeap(T) {
  import std.container : SList;
 
  private alias PowerForest = SList!PowerNode;
 
  private final class PowerNode {
  private {
  T payload_;
  uint rank_;
  PowerForest children_;
  }
  }
 
  final class PowerHeap {
  private {
  PowerNode top_;
  PowerForest forest_;
  uint size_;
  }
  }
 }
 
 unittest {
  PowerHeap!int h;
 }
there is a circular dependency in your data structures. you're defining
`PowerNode` in the terms of... `PowerNode`. this won't work.

your `PowerForest` definition depends of complete `PowerNode`
definition, but `PowerNode` definition depends of complete
`PowerForest` definition.

don't do that.


signature.asc
Description: PGP signature


Re: no size yet for forward reference for nested structures

2015-01-14 Thread qqiang via Digitalmars-d

On Wednesday, 14 January 2015 at 08:31:08 UTC, bearophile wrote:

qqiang:

I've googled and found no straightforward solution to this 
issue. The how can I modify my code to eliminate this error?


Your code gives me a different error (Error: PowerHeap!int is 
used as a type).


What if you replace the SList with a dynamic array?

Bye,
bearophile


Thanks for your reply.

I'm sorry that I've provided wrong code. This is the exact code:

---

template PowerHeap(T) {
import std.container : SList;

private alias PowerForest = SList!PowerNode;

private final class PowerNode {
private {
T payload_;
uint rank_;
PowerForest children_;
}
}

final class PowerHeap {
private {
PowerNode top_;
PowerForest forest_;
uint size_;
}
}
}

unittest {
PowerHeap!int h;
}

--
My compiler is v2.066.1


Re: no size yet for forward reference for nested structures

2015-01-14 Thread qqiang via Digitalmars-d

On Wednesday, 14 January 2015 at 08:31:13 UTC, Ali Çehreli wrote:
First a reminder that this sort of question is more suitable to 
the D.learn newsgroup.


On 01/13/2015 10:41 PM, qqiang wrote:

 The following code:
 ```D
 template PowerHeap(T) {
  import std.container : SList;

  private alias PowerForest = SList!PowerNode;

  private final class PowerNode {
  ...
  }

  final class PowerHead {
  ...
  }
 }

 unittest {
  PowerHeap!int h;
 }
 ```

I started with your code and produced the following one:

template PowerHeap(T) {
import std.container : SList;

private alias PowerForest = SList!PowerNode;

private final class PowerNode {
// ...
}

final class PowerHead {
// ...
}
}

unittest {
PowerHeap!int h;// -- Compilation error here
}

void main()
{}

 failed to compile and get the error: PowerHeap!int.PowerNode:
no size
 yet for forward reference.

What compiler and version are you using? I received a different 
error with the git head dmd:


  Error: PowerHeap!int is used as a type

The compiler is right, PowerHeap!int is a template 
instantiation that wraps a number of definitions. Did you mean 
one of those? The following compiles:


unittest {
PowerHeap!int.PowerHead h;// -- now compiles
}

 I've googled and found no straightforward solution to this
issue. The
 how can I modify my code to eliminate this error?

Please provide exact code so that... Oh, wait! I've just 
noticed that your error message has PowerHeap!int.PowerNode in 
it. Let me try with that:


unittest {
PowerHeap!int.PowerNode h;// -- this compiles as well
}

Yeah, please provide exact code. :)

Ali


Thanks for your reminder.

I'm sorry that I've provided wrong code. This is the exact code:

---

template PowerHeap(T) {
import std.container : SList;

private alias PowerForest = SList!PowerNode;

private final class PowerNode {
private {
T payload_;
uint rank_;
PowerForest children_;
}
}

final class PowerHeap {
private {
PowerNode top_;
PowerForest forest_;
uint size_;
}
}
}

unittest {
PowerHeap!int h;
}

--
My compiler is v2.066.1


no size yet for forward reference for nested structures

2015-01-13 Thread qqiang via Digitalmars-d

The following code:
```D
template PowerHeap(T) {
import std.container : SList;

private alias PowerForest = SList!PowerNode;

private final class PowerNode {
...
}

final class PowerHead {
...
}
}

unittest {
PowerHeap!int h;
}
```

failed to compile and get the error: PowerHeap!int.PowerNode: no 
size yet for forward reference.


I've googled and found no straightforward solution to this issue. 
The how can I modify my code to eliminate this error?