Thread overview
A devil self reference
Aug 15, 2018
Alex
Aug 15, 2018
Alex
Aug 15, 2018
Jonathan M Davis
Aug 15, 2018
Alex
August 15, 2018
Hi all.
Finally, I arrived at something like this:

´´´
void main()
{
	S!(sarr)[] sarr;
}

struct S(alias Reference)
{
	size_t id()
	in
	{
		// not static assert, only because a pointer is never known in advance
		assert(Reference.ptr <= &this);
	}
	do
	{
		return &this - Reference.ptr;
	}
}
´´´

Of course, this does not compile, because I try to use an identifier before I defined it.

However, the reason I dare to ask is, that all the stuff with the weird self reference is compile time known.

So, is there a possibility to define something like the thing above?
August 15, 2018
On Wednesday, 15 August 2018 at 16:40:49 UTC, Alex wrote:
> Hi all.
> Finally, I arrived at something like this:
>
> ´´´
> void main()
> {
> 	S!(sarr)[] sarr;
> }
>
> struct S(alias Reference)
> {
> 	size_t id()
> 	in
> 	{
> 		// not static assert, only because a pointer is never known in advance
> 		assert(Reference.ptr <= &this);
> 	}
> 	do
> 	{
> 		return &this - Reference.ptr;
> 	}
> }
> ´´´
>
> Of course, this does not compile, because I try to use an identifier before I defined it.
>
> However, the reason I dare to ask is, that all the stuff with the weird self reference is compile time known.
>
> So, is there a possibility to define something like the thing above?

containment in a container is also wanted...

struct Container
{
	S!(sarr)[] sarr;
}

but also not possible in this form because of a circular reference.
August 15, 2018
On Wednesday, August 15, 2018 10:40:49 AM MDT Alex via Digitalmars-d-learn wrote:
> Hi all.
> Finally, I arrived at something like this:
>
> ´´´
> void main()
> {
>   S!(sarr)[] sarr;
> }
>
> struct S(alias Reference)
> {
>   size_t id()
>   in
>   {
>       // not static assert, only because a pointer is never known in
> advance
>       assert(Reference.ptr <= &this);
>   }
>   do
>   {
>       return &this - Reference.ptr;
>   }
> }
> ´´´
>
> Of course, this does not compile, because I try to use an identifier before I defined it.
>
> However, the reason I dare to ask is, that all the stuff with the weird self reference is compile time known.
>
> So, is there a possibility to define something like the thing above?

What are you actually trying to do? Aside from the circular reference issues, using the address of a struct like that is very risky, because if the struct is ever moved, it will change. Also, even if the circular reference worked, the struct is then in a dynamic array on the heap, whereas the dynamic array itself is on the stack. So, you're trying to subtract a stack pointer from a heap pointer.

- Jonathan M Davis




August 15, 2018
On Wednesday, 15 August 2018 at 21:42:11 UTC, Jonathan M Davis wrote:
>
> What are you actually trying to do? Aside from the circular reference issues, using the address of a struct like that is very risky, because if the struct is ever moved, it will change.

Yeah... my functions are all ref. Or work with slices...

> Also, even if the circular reference worked, the struct is then in a dynamic array on the heap, whereas the dynamic array itself is on the stack. So, you're trying to subtract a stack pointer from a heap pointer.

Hm... didn't thought of that. Does this matter?


My current form is like that:

´´´
void main()
{
	S.c.sarr.length = 5;
	S.c.sarr[2 .. 4].usefulFun;
}

struct Container
{
	S[] sarr;
}

struct S
{
	static Container c;

	size_t id()
	{
		return &this - c.sarr.ptr;
	}

	void anotherUsefulFun()
	{
	    /*
                works on "neighbors" of this, which are only available,
                if c.sarr is "well-known"
            */
	}
}

void usefulFun(S[] slice)
{
	import std.stdio;
	writeln(slice[0].id);
}
´´´

It works. After a lot of debugging and head aches, it works as I want to. But, only until I try to copy the array, as you said.
I'm aware of the problem, and I worked it out so far, that on copies of the array sarr only the operations are done, which do not need the pointer stuff.

Like dumping the data, for example, or querying elementary properties. Even querying for id on a array copy is ok, if I do it with another function, let's call it indexOf :)
What doesn't work are the calls to "neighbor"-acting functions, but these are not needed on sarr copies.

The project is almost finished, so, I'm mainly after a learn effect now. What I'm looking for, is something what would simplify my structure. So... I can think at least of two things:
1. something, where I don't need the dangerous pointer stuff.
2. something, which works well after I copy it.

If the circular stuff worked, it would simplify my life a lot. I could define some constructors, for copying data between arrays, whereas the pointer stuff would maintain itself, as it would be "integrated" into the type. But ok, I see, that this is at least kind of strange...