Re: Static struct?

2019-04-24 Thread Rubn via Digitalmars-d-learn

On Wednesday, 24 April 2019 at 21:12:10 UTC, JN wrote:
I noticed a construct I haven't seen before in D when reading 
the description for automem - 
https://github.com/atilaneves/automem


 static struct Point {
int x;
int y;
}


What does "static" do in this case? How does it different to a 
normal struct?


You can access variables in the current scope when in a nested 
scope, static prevents this so that you don't accidentally access 
any of those values as it adds overhead to the struct.


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

void main() {
import std.stdio;

int x;
struct A {
 void test() { x = 10; }
}

static struct B {
// void test() { x = 20; } // Error
}

A a;
B b;

a.test();
// b.test();

writeln( x );
}


Re: How to pass variables to string mixins?

2019-02-25 Thread Rubn via Digitalmars-d-learn

On Tuesday, 26 February 2019 at 00:07:54 UTC, Victor Porton wrote:
I want to create a string mixin based on a supplementary 
variable (name2 below):


Let we have something like:

mixin template X(string name) {
  immutable string name2 = '_' ~ name;
  mixin("struct " ~ name2 ~ "{ int i; }");
}

But it would create variable name2 inside X, which should not 
be created. How to solve this problem?


Probably the easiest way is just to move it into another function 
outside so that it doesn't get mixed in with the mixin template.


 private string buildStructString(string name2) {
return "struct " ~ name2 ~ "{ int i; }"
 }

 mixin template X(string name) {
   mixin(buildStructString("_" ~ name));
 }


Re: Am I misusing with?

2019-01-19 Thread Rubn via Digitalmars-d-learn

On Saturday, 19 January 2019 at 17:49:31 UTC, faissaloo wrote:

This seems to work fine

file = File("test.txt", "r");
with (file)
{
  scope(exit) close();

  foreach (string line; file.lines())
  {
line_array ~= line;
  }
}

however:

file = File("test.txt", "r");
with (file)
{
  scope(exit) close();

  foreach (string line; lines())
  {
line_array ~= line;
  }
}

Tells me I'm attempting to read from an unopened file, what's 
going on here? It seems like I'm able to use lines() like this 
within with statements unless they're in my foreach iterator. 
Is this a bug or intended behaviour?


If you look at the implementation, "lines" is a struct.

https://github.com/dlang/phobos/blob/v2.084.0/std/stdio.d#L4330

I didn't know you could use structs with UFCS, which is why you 
are probably confused as well. It's a function defined in "file". 
If you use lines() by itself, you are constructing a new "lines" 
struct where the default File is an unopened file.


I tend to avoid "with" altogether because of things like this. It 
becomes hard to tell what is actually part of the struct and what 
is just UFCS. If you do want to use the object with UFCS you have 
to explicitly use the object anyways so the point is kind of mute.


UFCS if you don't know just means you can use global functions 
(and apparently structs) with the same syntax as if it were a 
member function:



struct testStruct {
this( int value ) {
import std.stdio : writeln;
writeln("testStruct - ", value);
}
}

void test(int value) {
import std.stdio : writeln;
writeln( value );
}

void main() {
10.test(); // prints 10
20.testStruct();
}

https://run.dlang.io/is/0Xpnmt


Re: Forward declaration inside Function block, no error?

2019-01-06 Thread Rubn via Digitalmars-d-learn

On Sunday, 6 January 2019 at 18:38:44 UTC, Benjamin Thaut wrote:

Today I found a bug in my D code.


import std.stdio;

// Type your code here, or load an example.
void grow()
{
writeln("grow");
}

void someFunc(bool condition)
{
if(condition)
{
void grow();
}
}


I tried to call the grow function, but accidentially copied the 
return value alongside the function name. I was wondering why 
this code compiles without errors. the "void grow();" becomes a 
no-op. In my opinion this could should not compile. Am I 
missing something here?


Kind Regards
Benjamin Thaut


import std.stdio;

void grow()
{
writeln("grow");
}

void someFunc(bool condition)
{
if(condition)
{
void grow();
pragma(msg, grow.mangleof); // _D3app8someFuncFbZ4growMFZv
}
}

You can declare functions inside of functions in D. You weren't 
forward declare grow() in the module namespace, so much as you 
were forward declaring a new function grow.




Re: How to initialize a globle variable nicely and properly?

2018-12-14 Thread Rubn via Digitalmars-d-learn

On Saturday, 15 December 2018 at 02:54:55 UTC, Heromyth wrote:
We have a module including many globle variables which are 
needed to be initialized firstly in "shared static this() {}", 
see here 
https://github.com/huntlabs/hunt/blob/master/source/hunt/time/Init.d.


The problem is that these variables are not always initialized 
firstly when are referenced by some others moudles in "static 
this() {}". Here is a demo to illustrate it.


//
// module A
//
module test.A;

import std.stdio;
import core.thread;
import core.time;

class A {
__gshared int sharedField;

shared static this() {
writeln("running A in shared static this(), 
sharedField=", sharedField);


Thread th = new Thread(() {  });
th.start();

Thread.sleep(100.msecs);
sharedField = 2;
writeln("running A done in shared static this(), 
sharedField=", sharedField);

}

static this() {
writeln("running A in static this(), sharedField=", 
sharedField);

}
}

//
// module B
//
module test.B;

import test.A;
import std.stdio;
import core.thread;

shared static this() {
writeln("running in shared static this() from B");
}

class B {
shared static this() {
writeln("running B in shared static this(), 
sharedField=", A.sharedField);

}

static this() {
// bug is here
writeln("running B in static this(), sharedField=", 
A.sharedField);

}
}

//
// module main
//
import std.stdio;

import test.A;
import core.thread;

void main()
{
writeln("running in main.");
}

//
// output
//
Running ./demo
running A in shared static this(), sharedField=0
running A in static this(), sharedField=0
running B in static this(), sharedField=0  // bug is here
running A done in shared static this(), sharedField=2
running in shared static this() from B
running B in shared static this(), sharedField=2
running A in static this(), sharedField=2
running B in static this(), sharedField=2
running main.



You can see the sharedField is 0 in B's static this() at first. 
If Thread is disabled to run in shared static this(), this 
problem seems to be fixed.


Some related bugs:
1) https://issues.dlang.org/show_bug.cgi?id=6114
2) https://issues.dlang.org/show_bug.cgi?id=4923


The problem here is that you are creating a new thread in the 
`shared static this()`.


shared static this() {
writeln("running A in shared static this(), 
sharedField=", sharedField);
Thread th = new Thread(() {  }); // Calls `static this()` 
including B's `static this()`

th.start();
Thread.sleep(100.msecs);
sharedField = 2;
writeln("running A done in shared static this(), 
sharedField=", sharedField);

}

static this() {
writeln("running A in static this(), sharedField=", 
sharedField);

}

Creating a new thread causes those thread's constructor `static 
this()` to be called. You need to create your threads somewhere 
else or have the values be initialized before the threads are 
created.


Re: difficulties with const structs and alias this / template functions

2018-11-18 Thread Rubn via Digitalmars-d-learn

On Sunday, 18 November 2018 at 17:30:18 UTC, Dennis wrote:
I'm making a fixed point numeric type and want it to work 
correctly with const. First problem:


```
const q16 a = 6;
a /= 2;  // compiles! despite `a` being const.
writeln(a);  // still 6
a.toQ32 /= 2;// what's actually happening
```

My q16 type has an implicit conversion to q32 (like how int can 
be converted to long):

```
q32 toQ32() const {
  return q32(...);
}
alias toQ32 this;
```
How do I make it so that a const(q16) will be converted to a 
const(q32) instead of mutable q32?


Second problem:
```
Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) {
import std.traits: Unqual;
Unqual!Q x = num;
// actual code
}
```
When I call this with a const(q16), Q is resolved to const(q16) 
so I have to unqualify Q every time. It works, but feels 
clumsy. Is there an easier way to automatically de-const 
parameters? We're working with small value types here, it 
should be simple.


If anyone knows any other pitfalls with const, I'd love to know 
them.


Yah most people tend to avoid const for this reason. It only 
really works for basic types, if you have a "const int" you can 
convert it to an "int" by copy. But if you have a type like 
Vector!(const int) that won't work, you can't even convert 
Vector!int to Vector!(const int) easily for example.



```
Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) {
import std.traits: Unqual;
Unqual!Q x = num;
// actual code
}
```


This is pretty much the only way, you can just add

alias V = Unqual!Q;

then use V in your function instead of Unqual!Q everywhere.


Re: UFCS syntax I never saw before.

2018-05-21 Thread Rubn via Digitalmars-d-learn

On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:

After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do 
with this kind of call?


I probably wouldn't use that. That wasn't what it was intended 
for and it's not really UFCS. It's was meant for properties that 
are defined as functions.


struct SomeStruct
{
void foo(int);
}

SomeStruct s;
s.foo = 10;

It's kind of horrible syntax for what it is doing, where it isn't 
obvious what is happening. Writeln and iota aren't setting 
anything, they are just function calls that happen to be able to 
take one parameter.


Re: C++ / const class pointer signature / unable to find correct D syntax

2018-05-06 Thread Rubn via Digitalmars-d-learn

On Friday, 4 May 2018 at 07:57:26 UTC, Uknown wrote:

On Friday, 4 May 2018 at 07:49:02 UTC, Robert M. Münch wrote:
I have a static C++ and can't make it to get a correct binding 
for one function:


DMD: public: unsigned int __cdecl b2d::Context2D::_begin(class 
b2d::Image & __ptr64,class b2d::Context2D::InitParams const * 
__ptr64 const) __ptr64
LIB: public: unsigned int __cdecl b2d::Context2D::_begin(class 
b2d::Image & __ptr64,class b2d::Context2D::InitParams const * 
__ptr64) __ptr64


So I somehow get some more const from D. This is the code I 
used:


   final uint _begin(ref Image image, const(InitParams) 
initParams);


Which creates a const pointer to a const class signature. But 
it should only be a const pointer. Any idea how to solve this?


The problem is that const in D is transitive. That means T * 
const from C++ is not expressible in D. Any reference through a 
const becomes const. To use it, IMO your best bet is to make a 
wrapper function on the C++ side like this:


unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & 
im,class b2d::Context2D::InitParams const * const InitParams)

{
return //the call to the original c++ function
}

Alternatively you can use dpp, or dstep or some similar tool to 
try and let the tool create bindings. As a last ditch, you can 
force the mangle to match by using pragma(mangle, ...) like 
this:


pragma(mangle, _ZactualMangleFromC++Compiler)
final uint _begin(ref Image image, const(InitParams) 
initParams);


Using pragma(mangle) isn't really a solution though, unless you 
only plan on using one platform/compiler. C++ doesn't have a 
single standard name mangling. You would need to get the name 
mangling for every compiler you plan to use then use a version 
define fore each. Which isn't really practical for how many 
bindings you would need to do that for.


The easiest solution is to just write C bindings for the C++ 
library then use those instead from D.


Re: C++ / Wrong function signature generated for reference parameter

2018-05-02 Thread Rubn via Digitalmars-d-learn

On Wednesday, 2 May 2018 at 21:55:31 UTC, Robert M. Münch wrote:

I have the following C++ function signature:

uint _begin(Image& image, const InitParams* initParams)
and the following D code:
 class InitParams {
 }
 class B2D {
   uint _begin(ref Image image, InitParams initParams);
 }
But this compiles to the following signature which is not found 
by the linker:
public: virtual unsigned int __cdecl 
b2d::Context2D::_begin(class b2d::Image * &,class 
b2d::InitParams *)
I don't understand why "ref Image" translates to "Image * &" 
and not "Image &". How can I get the C++ reference function 
signature written down in D?


If "Image" is a class then all classes are based as pointers to 
their respective object. So passing a ref to a class is kind of 
redundant. You want to use a struct which isn't passed by 
pointer, but by value. Which will then give you the signature you 
want.


Add property-like Function to Type ?

2018-04-24 Thread Rubn via Digitalmars-d-learn
I was wondering if I could create my own property in a way that 
can be used the same way as something like "T.sizeof". Right now 
I have the following to replace length:


uint length32(T)(T[] array)
{
return cast(uint)array.length;
}

I want something similar to be able to do the following:


uint size = T.sizeof32;

The closest I can think of is doing:

uint size = sizeof32!T


That's the best I can do, which is fine but I was wondering if 
there's any other way around that?


Re: Declare and Define Before Use? [rant]

2018-04-04 Thread Rubn via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 20:01:55 UTC, Ali wrote:

On Wednesday, 4 April 2018 at 19:51:27 UTC, kdevel wrote:

On Wednesday, 4 April 2018 at 19:19:30 UTC, Ali wrote:
BTW: You can't write

   void main ()
   {
  x.writeln;
  int x;
   }
   import std.stdio;



This is because x is not module scope
you can do this

   void main ()
   {
  x.writeln;

   }

   import std.stdio;
   int x;


Cause there's no scope at the module level.


struct A
{
A* a;

~this()
{
// use a
}
}

void main()
{
A b = A();
A a; // in this case "a" destructed before "b", but "b" uses 
"a"


}


Destruction and order of destruction becomes much more confusing. 
You also can't do scope(exit) at the module level for a reason. 
This mess shouldn't be allowed, it just makes it way worse to 
understand what is going on.




Re: Fast GC allocation of many small objects

2018-03-31 Thread Rubn via Digitalmars-d-learn

On Friday, 30 March 2018 at 20:46:43 UTC, Per Nordlöw wrote:
On Friday, 30 March 2018 at 20:38:35 UTC, rikki cattermole 
wrote:
Use a custom allocator (that could be backed by the GC) using 
std.experimental.allocators :)


https://dlang.org/phobos/std_experimental_allocator.html

is massive.

I guess I should allocate my nodes using

auto node = theAllocator.make!StrNode("alpha");

Could someone please give a working example of a GC-backed 
`theAllocator` suitable for my allocation pattern?


Be willing to change your code, the allocator can change at any 
point. What you implement today may not work tomorrow, what you 
fix to work for tomorrow may not end up working the next day (in 
terms of releases). That really should be something that is 
mentioned when you suggest using an experimential feature, 
there's no guarantees at all. It might not even get put into 
phobos. If your project is going to be used over the course of a 
year or more than maybe you shouldn't use it.


Re: Are there any working instructions about how to build and test dmd on Windows?

2018-03-13 Thread Rubn via Digitalmars-d-learn

Yah it's not fun.

Some notes:

You might need to set MSVC_CC environment variable cause it 
doesn't use the right format for VS path, depending on your 
version.


https://github.com/dlang/dmd/blob/v2.079.0/src/vcbuild/msvc-dmc.d#L19


You could open a command prompt with the batch file running which 
will add variables used by the script.


C:/Program Files (x86)/Microsoft Visual Studio 
14.0/VC/vcvarsall.bat



You should be able to build it now with just:

make -f win64.mak reldmd


When building druntime/phobos you need to pass the VCINSTALLDIR 
environment variable, but it has an unexpected "/" at the end of 
it so you need to remove it.


make -f win64.mak VCDIR="%VCINSTALLDIR:~0,-1%" DMD=../dmd/src/dmd

Didn't check if it works though I don't normally use batch/cmd.




Re: Setting up DMD on windows

2018-02-04 Thread Rubn via Digitalmars-d-learn

On Sunday, 4 February 2018 at 01:33:05 UTC, Seb wrote:

On Sunday, 4 February 2018 at 01:23:50 UTC, Rubn wrote:

On Saturday, 3 February 2018 at 23:42:28 UTC, welkam wrote:

[...]


I think you have to build with an old version of MSVC, 2010 
maybe? It's been a while since I built it I don't remember the 
exactly which version ended up working.


2013 and 2015 are tested on the CIs.


Wasn't that just added? I don't think that CI was running for the 
version he is trying to compile.


Re: Setting up DMD on windows

2018-02-03 Thread Rubn via Digitalmars-d-learn

On Saturday, 3 February 2018 at 23:42:28 UTC, welkam wrote:
Tried to use DMD compiler that I built from source by following 
these instructions https://wiki.dlang.org/Building_under_Windows


They are outdated but I managed to compile it but I get this 
error when I tried to compile some code.


dmdm -run Main.d
C:\D\dmd2\windows\32\..\..\src\druntime\import\core\sys\windows\winbase.d(1828):
 Error:
object.Error@(0): Access Violation

0x0064FED6
0x006502BE
0x006499CF
0x006488ED



dmdm is just alias dmdm=C:\D\dmd2\windows\32\dmd.exe $*

the compiler version is dmd-2.078.0

Could some one help fix this?


I think you have to build with an old version of MSVC, 2010 
maybe? It's been a while since I built it I don't remember the 
exactly which version ended up working.




Union Initialization

2018-01-30 Thread Rubn via Digitalmars-d-learn


Is there any way to initialize an array of unions with more than 
just the first union type?



struct A { float a; }
struct B { uint b; }

union Test
{
A a;
B b;
}

Test[2] test =
[
Test(A(1.0f)),
Test(B(10)), // ERROR
];


AFAIK there's no way to specify to use D with an initializer:

Test test = { b: B(10) };


Re: New integer promotion rules

2018-01-17 Thread Rubn via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote:

code like "m = n < 0 ? -n : n" doesn't worth a wrapper


That code is worth a wrapper, it's called "abs"...

m = abs(n);




Re: New integer promotion rules

2018-01-17 Thread Rubn via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote:

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max);


The generic code above (which worked for all signed integral 
types T in 2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
   auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
   auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my 
project.


Or write some wrapper code, which you prob should have done in 
the first place if you use that all around your project:


auto max = myMaxFunc!(isNegative, T);